首页 > 解决方案 > 如何在 Asynctask 中调用 Mainactivity 方法进行后台工作?

问题描述

我想要一个方法(在 MainActivity 中)从doInBackground(File... file)MyAsynctask 类(在 MainActivity 中)的方法中调用,并且该方法必须在后台工作,因为它需要时间并且我的应用程序停止工作片刻并且没有任何对话框出现我在onPreExecute()方法中调用如何解决问题的方法是我的代码,它工作得很好,但花费了太多时间,我的应用程序看起来挂了,但实际上并非如此。

ArrayList<HashMap<String,String>> getPlayList(File rootFolder) {
    ArrayList<HashMap<String,String>> fileList = new ArrayList<>();

    try {
        File[] files = rootFolder.listFiles();
         //here you will get NPE if directory doesn't contains  any file,handle it like this.
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory() && !file.isHidden()) {
                    if (true) {
                        fileList.addAll(getPlayList(file));
                    }
                    else {
                        break;
                    }
                } else if (file.getName().endsWith(".pdf")) {
                    HashMap<String, String> song = new HashMap<>();
                    song.put("file_path", file.getAbsolutePath());
                    song.put("file_name", file.getName());
                    fileList.add(song);
                }
            }
        }
        return fileList;
    } catch (Exception e) {
        return null;
    }
}

Asynctask 类在下面..

private class AsyncTaskExample extends AsyncTask<File, String, ArrayList> {


    @Override
    protected ArrayList doInBackground(File... file) {

        ArrayList<HashMap<String,String>> songList=getPlayList(folder);
        if(songList!=null){
            for(int i=0;i<songList.size();i++){
                final String fileName=songList.get(i).get("file_name");
                final String filePath=songList.get(i).get("file_path");

            //saving filePath and filName in SQLite Database..
                saveFileToDatabase(filePath, fileName);

            }
        }
        return songList;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        p = new ProgressDialog(MainActivity.this);
        p.setMessage("Please wait...Loading..");
        p.setIndeterminate(false);
        p.setCancelable(false);
        p.show();
    }

    @Override
    protected void onPostExecute(ArrayList arrayList) {
        super.onPostExecute(arrayList);
        if (mFiles != null)
        {
            p.dismiss();
        }
        else
        {
            p.show();
        }
    }
}

如何高效地完成工作?

解决方案

问题是下面给出的这些代码行:

AsyncTaskExample taskExample = new AsyncTaskExample();
        folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
      //I was writing this below line..
        taskExample.doInBackground(folder);

      //but it should be like in line below..
      taskExample.execute(folder);

标签: javaandroidarraylistandroid-asynctaskbackground

解决方案


我建议你定义一个回调,并在你的 asynctask 的构造函数中传递它,这样你就可以通知你的主要活动在需要时显示对话框。

打回来

public interface AsyncTaskExampleCallback {
    public void onShowDialog();
    public void onHideDialog();
}

异步任务

class AsyncTaskExample extends AsyncTask<File, String, ArrayList> {

    @Nullable
    private AsyncTaskExampleCallback callback = null;

    public AsyncTaskExample(@NotNull AsyncTaskExampleCallback callback) {
        this.callback = callback;
    }

    @Override
    protected ArrayList doInBackground(File... file) {

        ArrayList<HashMap<String, String>> songList = getPlayList(folder);
        if (songList != null) {
            for (int i = 0; i < songList.size(); i++) {
                final String fileName = songList.get(i).get("file_name");
                final String filePath = songList.get(i).get("file_path");

                //saving filePath and filName in SQLite Database..
                saveFileToDatabase(filePath, fileName);

            }
        }
        return songList;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (callback != null) {
            callback.onShowDialog();
        }
    }

    @Override
    protected void onPostExecute(ArrayList arrayList) {
        super.onPostExecute(arrayList);
        if (mFiles != null) {
            if (callback != null) {
                callback.onHideDialog();
            }
        } else {
            if (callback != null) {
                callback.onShowDialog();
            }
        }
    }
}

主要活动

public class MainActivity extends AppCompatActivity implements AsyncTaskExampleCallback {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new AsyncTaskExample(this).execute();
    }

    @Override
    public void onShowDialog() {
        //Show dialog here
    }

    @Override
    public void onHideDialog() {
        //Hide dialog here
    }
}

推荐阅读