重新打开应用程序

时间:2017-11-24 07:53:46

标签: java android android-fragments android-asynctask

目前,我的AsyncTask内有一个RecyclerView.Adapter被调用,其中我正在从网址下载文件并且我的ViewHolder内部正在显示进度我的AsyncTask看起来:

public class DownloadFileFromURL extends AsyncTask<String, String, String> {

    int positionnumber;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    @Override
    protected String doInBackground(String... f_url) {
        int count;
        String pathreference = f_url[0] + ",";

        positionnumber = Integer.parseInt(f_url[0]);
        isDownloading.set(positionnumber, true);
        try {
            URL url = new URL(f_url[1]);
            URLConnection conection = url.openConnection();
            conection.connect();

            // this will be useful so that you can show a tipical 0-100%
            // progress bar
            int lenghtOfFile = conection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(url.openStream(),
                    8192);
            if (isCancelled()) {
                return null;
            }

            if (a.equals("one")) {
                // Output stream
                OutputStream output = new FileOutputStream(Environment
                        .getExternalStorageDirectory().toString()
                        + "/" + setDownloadedName + ".mp4");


                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    if (isCancelled()) {
                        input.close();
                        return null;
                    }
                    publishProgress("" + (int) ((total * 100) / lenghtOfFile));

                    // writing data to file
                    output.write(data, 0, count);
                }

                // flushing output
                output.flush();
                pathreference = pathreference + Environment.getExternalStorageDirectory().toString() + "/" + setDownloadedName + ".mp4";
                // closing streams
                output.close();
                input.close();


            }
        } catch (Exception e) {
            Log.e("Error: ", e.getMessage());
        }

        return pathreference;
    }


    protected void onProgressUpdate(String... progress) {

        prog = progress[0];

        Log.d("Progress", progress[0]);
        bars.get(positionnumber).setProgress_(Float.parseFloat(progress[0]));
        float p = bars.get(positionnumber).getProgress_();
        if (p % 1 == 0)
            notifyItemChanged(positionnumber);

    }

    @Override
    protected void onPostExecute(String file_url) {

        String[] split = file_url.split(",");
        int index1 = Integer.parseInt(split[0]);

        try {

            videoHolderClass.get(index1).setImage(imgres[0]);
            bars.get(index1).setProgress_(0);
            manager.insertVideoPath(index1 + "", split[1]);
            RecyclerVideoAdapter.this.notifyItemChanged(index1);
            isDownloading.set(index1, false);
            Log.d("done", "filesaved");

        } catch (Exception e) {

            Log.e("Error: ", e.getMessage());
            Toast.makeText(c, "Network Error..", Toast.LENGTH_SHORT).show();

            prog = "";
            networkFailed = "yes";
            videoHolderClass.get(index1).setImage(imgres[1]);
            bars.get(index1).setProgress_(0);
            RecyclerVideoAdapter.this.notifyItemChanged(index1);
            isDownloading.set(index1, false);

        }
    }
}

RecyclerView位于片段内,片段填充在Activity - ViewPager中。

现在,每当我关闭活动或转到新活动并返回时,都不会再显示进度。

我见过人们会做以下事情:

if(mtask.getStatus() == AsyncTask.Status.FINISHED){
    // My AsyncTask is done and onPostExecute was called
}

但问题是AsyncTaskAdapter中,所以我无法在我的片段中引用它。

我的问题:

有人可以向我解释一下,查看AsyncTask是否正在运行的正确方法是什么,并在重新创建活动时更新进度?

1 个答案:

答案 0 :(得分:0)

我知道这不是&#34;正确&#34;这样做的方式 ,但我已经设法找到了解决办法,它适用于我想要实现的目标。

我决定使用SharedPreferences检查文件是否正在下载。在我的onPreExecute中,我执行了以下操作:

@Override
    protected void onPreExecute() {
        super.onPreExecute();
        SharedPreferences sharePrefss = c.getSharedPreferences("busyDownloading", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharePrefss.edit();
        editor.putString("isItBusy", "yes");
        editor.apply();
    }

上面我存储了一个String名为&#34; isItBusy&#34;我把它设置为是。

然后在onPostExecute我将SharedPreferences更改为:

SharedPreferences sharePrefss = c.getSharedPreferences("busyDownloading", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharePrefss.edit();
            editor.putString("isItBusy", "no");
            editor.apply();

在我的Activity中,当用户按下后退按钮时,我会执行以下操作:

@Override
public void onBackPressed() {
    SharedPreferences sharePrefs = getSharedPreferences("busyDownloading", Context.MODE_PRIVATE);
    String getSharedUser = sharePrefs.getString("isItBusy", "");
    if (getSharedUser.equals("yes")){
        // AsyncTask - onPostExecute was not called = moveTaskToBack
        moveTaskToBack(true);
    }else {
        //AsyncTask - onPostExecute was called and application can be destroyed
        finish();
    }
}

通过以上操作,我现在知道文件是否仍在忙于下载并相应地处理后退按钮。

下一个问题是处理设备的旋转,因为当设备旋转时,Activity会被销毁并再次创建。

要解决这个问题,我做的第一件事就是通过将setRetainInstance(true);添加到我的片段onCreateView来保留片段状态。然后在我的清单中,我将android:configChanges="orientation|screenSize"添加到我的Activity

这样做解决了轮换问题。

@vsatkh提到的最后一个问题是对下载进行排队。我下载的文件不是那么大(最多约2-5MB)。所以我决定一次只启用一次下载,同时检查SharedPreferences,如下所示:

holder.setItemClickListener(new ItemClickListener() {

        @Override
        public void onItemClick(View v, int pos) {

            SharedPreferences sharePrefs = c.getSharedPreferences("busyDownloading", Context.MODE_PRIVATE);
            String getSharedUser = sharePrefs.getString("isItBusy", "");
            if (getSharedUser.equals("yes")){
                Toast.makeText(c, "You can only download one file at a time...", Toast.LENGTH_SHORT).show();

            }else {
             DownloadFileFromURL p = new DownloadFileFromURL();
             p.execute(pos + "", downloadLink);

            }

        }
    });

上面不包括我使用的所有方法(比如检查文件是否已存在),只包括与我问的问题相关的方法。