简体   繁体   English

Android开发:在单独的类文件中使用AsyncTask

[英]Android Development: Having an AsyncTask in a separate class file

I have been playing around with various examples trying to familiarize myself with AsyncTask. 我一直在玩各种试图熟悉AsyncTask的例子。 So far all the examples I have seen have had the AsyncTask included into the onCreate method of the main activity. 到目前为止,我看到的所有示例都将AsyncTask包含在主要活动的onCreate方法中。 Which I don't like very much, so I was wanting to see how hard it would be to separate it into its own class. 我不太喜欢,所以我想看看将它分成自己的课程有多难。 So far I have this: 到目前为止我有这个:

the main activity 主要活动

package com.example.asynctaskactivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.example.asynctaskactivity.ShowDialogAsyncTask;

public class AsyncTaskActivity extends Activity {

 Button btn_start;
 ProgressBar progressBar;
 TextView txt_percentage;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn_start = (Button) findViewById(R.id.btn_start);
        progressBar =  (ProgressBar) findViewById(R.id.progress);
        txt_percentage= (TextView) findViewById(R.id.txt_percentage);
        Log.v("onCreate","Attempt set up button OnClickListener");
        btn_start.setOnClickListener(new View.OnClickListener() 
        { 
           @Override
           public void onClick(View v) {
               btn_start.setEnabled(false);
               new ShowDialogAsyncTask().execute();
           }
        });

        Log.v("onCreate","Success!"); 
    }
}

the new seperate AsyncTask class 新的单独的AsyncTask类

package com.example.asynctaskactivity;

import android.os.AsyncTask;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{
int progress_status;

@Override
    protected void onPreExecute() {
    // update the UI immediately after the task is executed
    Log.v("onPreExecute","1");
    super.onPreExecute();
    Log.v("onPreExecute","2");
    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPreExecute()", Toast.LENGTH_SHORT).show();
    progress_status = 0;
    Log.v("onPreExecute","3");
    txt_percentage.setText("downloading 0%");  
    Log.v("onPreExecute","4");
    }

    @Override
    protected Void doInBackground(Void... params) {
        Log.v("doInBackground","1");
        while(progress_status<100){

            progress_status += 2;

            publishProgress(progress_status);
            SystemClock.sleep(300);

        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);

    progressBar.setProgress(values[0]);
    txt_percentage.setText("downloading " +values[0]+"%");   
    }

    @Override
    protected void onPostExecute(Void result) {
    super.onPostExecute(result);

    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPostExecute()", Toast.LENGTH_SHORT).show();

    txt_percentage.setText("download complete");
    btn_start.setEnabled(true);
    }
}

Originally this was all in the main activity, hence the mentions to the elements that the asynctask should in theory update. 最初这一切都在主要活动中,因此提到了asynctask理论上应该更新的元素。 Obviously at present this is causing runtime errors, which then got me thinking. 显然目前这会导致运行时错误,这让我想到了。 How can I have the file seperate but still update the UI thread. 如何使文件分离,但仍然更新UI线程。

Sorry if this is a stupid question, quite new to android development and background threads in particular. 很抱歉,如果这是一个愚蠢的问题,特别是Android开发和后台线程的新手。

How can I have the file seperate but still update the UI thread. 如何使文件分离,但仍然更新UI线程。

Okey. 好。 So at first you know that main advantage of AsyncTask added in Activity as inner class is that you have direct access to all UI elements and it makes possible pretty "lightweight" UI updates. 所以首先你知道在Activity中添加的AsyncTask作为内部类的主要优点是你可以直接访问所有UI元素,并且它可以实现非常“轻量级”的UI更新。

But if you decided to make AsyncTask separated from Activity(which also have some benefits eq code is more clean and app logic is separated from appearance) class you can: 但是如果你决定将AsyncTask与Activity分开(这也有一些好处,eq代码更干净,app逻辑与外观分离),你可以:

This is all what you need i guess. 这就是我猜你需要的一切。

Add a callback interface, and let your Activity implement it. 添加一个回调接口,让Activity实现它。

public interface MyAsyncTaskCallback{
    public void onAsyncTaskComplete();
}

In the postexecute: 在postexecute中:

myAsyncTaskCallback.onAsyncTaskComplete();

In the constructor of your AsyncTask you could pass the instance of MyAsyncTaskCallback (your Activity ). AsyncTask的构造函数中,您可以传递MyAsyncTaskCallback (您的Activity )的实例。

Your best way of handling this is via a Handler. 处理此问题的最佳方法是通过处理程序。 Instantiate one in the activity and override the method handleMessage() . 在活动中实例化一个并覆盖方法handleMessage() When you create ShowDialogAsyncTask class just pass in the handler and maintain a reference to it. 当您创建ShowDialogAsyncTask类时,只需传入处理程序并维护对它的引用。 On postExecute you can construct a message and send it via the handler method sendMessage() . postExecute您可以构造一条消息并通过处理程序方法sendMessage()发送它。

A previous answer mentioned using an interface and a callback paradigm. 之前的回答提到了使用接口和回调范例。 This will work, however, there is a chance that the activity can be destroyed and won't be present when the postExecute method is executed so you would need to test for this. 这将起作用,但是,当执行postExecute方法时,活动可能会被销毁并且不会出现,因此您需要对此进行测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM