Как Java бросает работу оператора?

Я также использовал другой способ загрузки файла с сервера.

Первый, который вы уже используете как DowanloadManager

Второй - использовать AsyncTask для загрузки файла.

class DownloadTask : AsyncTask<String, Int, String>() {

    lateinit var downloadTaskListener: DownloadTaskListener
    lateinit var pm: PowerManager
    private var mWakeLock: PowerManager.WakeLock? = null
   // private lateinit var mProgressBar: ProgressBar
    private var fileName: String? = null
    private var fileNameWithoutExtn: String? = null
    private val dialog: Dialog? = null
   // private var alertDialog: AlertDialog? = null
    //lateinit var txtFileSize: TextView
    internal var total: Long = 0
    private var fileLength: Int = 0

    //lateinit var btnCancel: Button


    override fun doInBackground(vararg sUrl: String): String? {
        var input: InputStream? = null
        var output: OutputStream? = null
        var connection: HttpURLConnection? = null
        var outPutFile: File? = null
        try {
            val url = URL(sUrl[0])
            connection = url.openConnection() as HttpURLConnection
            connection.connect()

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.responseCode != HttpURLConnection.HTTP_OK) {
                return ("Server returned HTTP " + connection.responseCode
                        + " " + connection.responseMessage)
            }

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            fileLength = connection.contentLength

            // download the file
            input = connection.inputStream
            fileName = sUrl[0].substring(sUrl[0].lastIndexOf('/') + 1, sUrl[0].length)

            fileNameWithoutExtn = fileName!!.substring(0, fileName!!.lastIndexOf('.'))
            Log.d("check", "name $fileName without extention $fileNameWithoutExtn")
            outPutFile = downloadTaskListener.getFilePath("$fileNameWithoutExtn.apk")
            output = FileOutputStream(outPutFile)

            val data = ByteArray(4096)
            total = 0
            var count: Int=input.read(data)
            while (count != -1) {
                // allow canceling with back button or click on Cancel button
                if (isCancelled) {
                    output.flush()
                    output.close()
                    input!!.close()
                    return null
                }
                total += count.toLong()
                // publishing the progress....
                if (fileLength > 0)
                // only if total length is known
                    Log.d("check", total.toString() + "")
                publishProgress((total * 100 / fileLength).toInt())
                output.write(data, 0, count)
            }
        } catch (e: Exception) {
            return e.toString()
        } finally {
            try {
                output?.close()
                input?.close()
               // outPutFile!!.setReadable(true, false)


            } catch (ignored: IOException) {
            }

            connection?.disconnect()
        }
        return null
    }

    override fun onPreExecute() {
        super.onPreExecute()
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
//        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        mWakeLock = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            javaClass.name
        )
        mWakeLock!!.acquire()

//
//        val dialogBuilder = AlertDialog.Builder(context)
//        // ...Irrelevant code for customizing the buttons and title
//        val inflater = LayoutInflater.from(context)
//        val customProgress = inflater.inflate(R.layout.custom_progress_dialog, null)
//        dialogBuilder.setView(customProgress)
//
//        alertDialog = dialogBuilder.create()
//        alertDialog!!.setCancelable(false)
//
//        mProgressBar = customProgress.findViewById(R.id.downloadProgressBar)
//        mProgressBar!!.progressDrawable = context.resources.getDrawable(R.drawable.custom_progress)
//        txtFileSize = customProgress.findViewById(R.id.txt_file_size)
//        txtFileSize.text = "Downloading is starting ...."
//        btnCancel = customProgress.findViewById(R.id.btnCancel)
       downloadTaskListener.showDialog()
//        txtFileSize= alertDialog!!.txt_file_size
//        mProgressBar= alertDialog!!.downloadProgressBar
//        btnCancel= alertDialog!!.btnCancel
        downloadTaskListener.getCancelButton().setOnClickListener { cancel(true) }
        downloadTaskListener.updateDialogData(0,"Downloading is starting ....")
        //        dialog.show();
      //  alertDialog!!.show()

        downloadTaskListener.showDialog().show()
    }

    // Display the async tas progress
    override fun onProgressUpdate(vararg values: Int?) {
        downloadTaskListener.updateDialogData(values[0]!!,"Download progress : " + Utils.bytes2String(total) + "/" + Utils.bytes2String(fileLength.toLong()))
//        mProgressBar.progress = values[0]!!
//        mProgressBar.setMax(100)
//        txtFileSize.text = "Download progress : " + Utils.bytes2String(total) + "/" + Utils.bytes2String(fileLength.toLong())
       // downloadTaskListener.showToast("Downloaded ${values[0]} %")
        super.onProgressUpdate(values[0])
    }


    override fun onPostExecute(result: String?) {
        mWakeLock!!.release()
        //mProgressDialog.dismiss();
        //dialog.dismiss();
        downloadTaskListener.showDialog()!!.dismiss()
        if (result != null)
//            Toast.makeText(context, "Download error: $result", Toast.LENGTH_LONG).show()
        downloadTaskListener.showToast("Download error: $result")
        else {
//            Toast.makeText(context, "Apk downloaded", Toast.LENGTH_SHORT).show()
            downloadTaskListener.showToast("Apk downloaded")
           // txtFileSize.text = "APK Downloaded Completely."
            downloadTaskListener.updateDialogData(100,"APK Downloaded Completely.")
           // val file = File(Utils.getAbsoluteFile("", context), "$fileNameWithoutExtn.apk")
            val file=downloadTaskListener.getFilePath("$fileNameWithoutExtn.apk")
            //File file = new File("/sdcard/update.apk");
            var fileUri = Uri.fromFile(file)
            if (file.exists()) {
                Log.d("check", "file exists " + file.absolutePath + fileUri)
            } else {
                Log.d("check", "file does not exist " + file.absolutePath)
            }
            if (Build.VERSION.SDK_INT >= 24) {
//                fileUri = FileProvider.getUriForFile(
//                    context,
//                    context.applicationContext.packageName + ".my.package.name.provider",
//                    file
//                )
            }
            val intent = Intent(Intent.ACTION_VIEW, fileUri)
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
            intent.setDataAndType(fileUri, "application/vnd.android" + ".package-archive")
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
//            context.startActivity(intent)
            downloadTaskListener.startActivity(intent)
        }

    }

    override fun onCancelled(s: String) {
        super.onCancelled(s)
        Log.d("TASK TAG", "Cancelled.")
      //  txtFileSize.text = "Downloading Cancelled"
//        Toast.makeText(context, "Downloading Cancelled ", Toast.LENGTH_SHORT).show()
        downloadTaskListener.showToast("Downloading Cancelled ")
//        mProgressBar!!.progress = 0
        //alertDialog!!.dismiss()
        downloadTaskListener.updateDialogData(0, "Downloading Cancelled")
        downloadTaskListener.showDialog().dismiss()

    }

    interface DownloadTaskListener{
        fun showToast(text: String)
        fun startActivity(intent: Intent)
        fun getFilePath(fileName:String):File
        fun showDialog():AlertDialog
        fun updateDialogData(progress:Int,msg:String)
        fun getCancelButton():Button
    }
}

3-й, который, я думаю, лучше всего подходит для больших файлов, чтобы загрузить файл, используя стороннюю библиотеку. Сетевая библиотека Android сначала поставит библиотеку в gradle

implementation 'com.amitshekhar.android:android-networking:1.0.2'

, затем напишет этот код

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                      // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                      // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                      // handle error    
                    }
                }); 
11
задан James McMahon 8 May 2009 в 15:15
поделиться

4 ответа

Достаточно ли хорош JLS ?

Преобразование приведения применяется к операнду оператора приведения (§15.16): тип выражения операнда должен быть преобразован к типу, явно названному оператором приведения. Контексты приведения позволяют использовать:

  • преобразование идентичности (§5.1.1)
  • расширяющееся примитивное преобразование (§5.1.2)
  • сужающее примитивное преобразование (§5.1.3)
  • расширение преобразование ссылки (§5.1.5), необязательно, за которым следует неконтролируемое преобразование (§5.1.9)
  • , преобразование сужающей ссылки (§5.1.6), необязательно, за которым следует неконтролируемое преобразование
  • преобразование упаковки (§5.1.7) )
  • преобразование распаковки (§5.1.8).

На самом деле, может быть эта часть более актуальна: S - это тип класса:

  • Если T - тип класса, то либо | S | <: | T |, или | T | <: | S |; в противном случае время компиляции возникает ошибка. Кроме того, если есть существует супертип X из T и супертип Y из S , так что и X , и Y доказуемо различны параметризованные типы (§4.5), и что стирание X и Y то же самое, время компиляции возникает ошибка.
  • Если T является типом интерфейса:
    • Если S не является финальным класс (§8.1.1), тогда, если существует супертип X из T и супертип Y из S , так что оба X и Y доказуемо различные параметризованные типы, и что стирание X и Y такие же, ошибка времени компиляции происходит. В противном случае актерский состав всегда допустимо во время компиляции (потому что даже если S не реализует T , подкласс S might).
    • Если S является последний класс (§8.1.1), тогда S должен реализовать T , или возникает ошибка времени компиляции.

  • Если T это переменная типа, тогда это алгоритм применяется рекурсивно, используя верхнюю границу T в место Т .
  • Если T - тип массива, тогда S должен быть класс Объект или происходит ошибка времени компиляции.
  • Если S - тип интерфейса:
    • Если T - тип массива, тогда T должен реализовать S , или время компиляции возникает ошибка.
    • Если T - это тип, который не финал (§8.1.1), тогда, если существует супертип X из T и супертип Y из S , так что оба X и Y доказуемо различные параметризованные типы, и что стирание X и Y такие же, ошибка времени компиляции происходит. В противном случае актерский состав всегда допустимо во время компиляции (потому что даже если T не реализует S , подкласс T might).
    • Если T является тип, который является final , затем:
      • Если S не является параметризованным тип или необработанный тип, тогда T должен реализовать S , и приведение статически известно, чтобы быть правильным, или происходит ошибка времени компиляции.
      • В противном случае, S либо параметризованный тип, который является вызовом некоторых объявление универсального типа G или необработанный тип, соответствующий универсальному объявление типа G . То есть должен существовать супертип X из T , так что X является вызов G , или происходит ошибка времени компиляции. Кроме того, если S и X доказуемо различны параметризованы типы, затем ошибка времени компиляции происходит.
  • Если S - переменная типа, тогда этот алгоритм применяется рекурсивно, используя верхняя граница S вместо S .
  • Если S - это тип массива SC [], то есть массив компонентов введите SC :
    • Если T является тип класса, то если T не Объект , затем возникает ошибка времени компиляции (потому что Объект - единственный класс тип, которому могут быть присвоены массивы).
    • Если T - это тип интерфейса, тогда ошибка времени компиляции возникает, если T - это тип java.io.Serializable или тип Cloneable , только интерфейсы, реализованные массивами.
    • Если T является переменной типа, то:
      • Если верхний граница T равна Объект или тип java.io.Serializable или тип Cloneable или переменная типа, которую S может законно быть преобразованным рекурсивно применяя эти правила, то приведение законный (хотя и не отмечен).
      • Если верхний граница T - это тип массива TC [] , затем ошибка времени компиляции возникает, если тип SC [] не может приводиться к TC [] рекурсивным применение этих во время компиляции правила кастинга.
      • В противном случае происходит ошибка времени компиляции.
    • Если T - тип массива TC [], то есть массив компонентов типа TC , тогда возникает ошибка времени компиляции если не выполняется одно из следующих условий:
    • TC и SC являются тот же примитивный тип.
    • TC и SC - ссылочные типы и тип SC можно преобразовать в TC с помощью рекурсивное применение этих правила для приведения во время компиляции.

  • Теперь совершенно ясно, не так ли? : D

    Другими словами, это лучшее, что я могу сделать, не зная подробностей о вашей проблеме.

    10
    ответ дан 3 December 2019 в 05:13
    поделиться

    Вероятная причина mystifcation приведения классов в том, что не только типы должны совпадать, но и загружаться одним и тем же загрузчиком классов.

    Вы должны иметь возможность выгружать не только иерархия типов, но также и идентификатор загрузчика классов для каждого класса.

    Подобные проблемы не редкость в средах в стиле сервера приложений, где код приложения и код инфраструктуры намеренно изолированы - например, если системные классы случайно включены в JAR приложения, которые вы может иметь две копии «одного и того же» класса в JVM, и жизнь становится запутанной

    6
    ответ дан 3 December 2019 в 05:13
    поделиться

    Приведение утверждает, что тип среды выполнения объекта совместим с заданным статическим типом, и, таким образом, позволяет вызывать методы этого типа для объекта.

    Здесь obj - это объект типа Integer, но доступный только через ссылку на объект:

    Object obj = new Integer(1);
    

    Приведение позволяет вам снова обрабатывать его как Integer (или некоторый суперкласс Integer):

    System.out.println(((Integer) obj).intValue());
    

    ClassCastException occours когда указанный статический тип не соответствует типу среды выполнения объекта:

    System.out.println(((Float) obj).intValue()); // runtime error
    

    Вы можете найти тип среды выполнения любого объекта с помощью getClass () и различных методов класса:

    System.out.println(obj.getClass()); // prints "class java.lang.Integer"
    
    3
    ответ дан 3 December 2019 в 05:13
    поделиться

    Другие полезные и авторитетные ссылки можно найти в Спецификации виртуальной машины Java, в частности §2.6.5, «Сужение ссылочных преобразований», и особенно в определении checkcast инструкция.

    3
    ответ дан 3 December 2019 в 05:13
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: