java - 如何调用Asynctask中的Mainactivity方法进行后台工作?

标签 java android arraylist android-asynctask background

我想要一个方法(存在于 MainActivity 中)从 MyAsynctask 类(存在于 MainActivity 中)的 doInBackground(File... file) 方法调用,并且该方法必须在后台工作,因为这需要时间,我的应用程序暂时停止工作,并且没有出现我在 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);

最佳答案

我建议您定义一个回调,并将其传递到异步任务的构造函数中,以便您可以通知您的主要 Activity 在需要时显示对话框。

回调

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();
            }
        }
    }
}

主要 Activity

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
    }
}

关于java - 如何调用Asynctask中的Mainactivity方法进行后台工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61284840/

相关文章:

java - 在 Java 中使用 Thread 进行 ArrayList<object> 操作

android - 使用 Gluon 移动环境时如何在运行时请求权限?

php - 通过PHP从Android向MySQL插入一条记录(包括本地当前TIME)的方法

java - 如何每隔 2 小时自动启动 Tanuki Software Wrapper

java - 如何在 Zuul post filter 中获取响应体?

android - 如何在 android 中使用 retrace.bat

java - 为什么我不能在迭代器上调用特定的类方法?

java - 为什么 Java 设计者不制作这样的列表 ---new ArrayList ("1","2")

java - Netty - channel 写入无法将数据发送到客户端

javascript - jsp中如何通过点击href标签传递数据