java Android 开发:在单独的类文件中有一个 AsyncTask

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15487807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 19:45:47  来源:igfitidea点击:

Android Development: Having an AsyncTask in a separate class file

javaandroidandroid-asynctask

提问by cosmicsafari

I have been playing around with various examples trying to familiarize myself with AsyncTask. So far all the examples I have seen have had the AsyncTask included into the onCreate method of the main activity. 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:

我一直在玩各种示例,试图让自己熟悉 AsyncTask。到目前为止,我看到的所有示例都将 AsyncTask 包含在主活动的 onCreate 方法中。我不太喜欢它,所以我想看看将它分成自己的类有多难。到目前为止,我有这个:

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

最初这一切都在主要活动中,因此提到了 asynctask 理论上应该更新的元素。显然,目前这会导致运行时错误,这让我开始思考。如何将文件分开但仍更新 UI 线程。

Sorry if this is a stupid question, quite new to android development and background threads in particular.

对不起,如果这是一个愚蠢的问题,特别是对于 android 开发和后台线程来说,这是一个新问题。

回答by Simon Dorociak

How can I have the file seperate but still update the UI thread.

如何将文件分开但仍更新 UI 线程。

Okey. So at first you know that main advantage of AsyncTaskadded in Activity as inner class is that you have direct access to all UI elements and it makes possible pretty "lightweight" UI updates.

好的。因此,首先您知道AsyncTask将 Activity 添加为内部类的主要优点是您可以直接访问所有 UI 元素,并且可以实现非常“轻量级”的 UI 更新。

But if you decided to make AsyncTask separated from Activity(which also have some benefits e.q. code is more clean and app logic is separated from appearance) class you can:

但是,如果您决定将 AsyncTask 与 Activity 分开(这也有一些好处 eq 代码更干净并且应用程序逻辑与外观分离)类,您可以:

This is all what you need i guess.

我猜这就是你所需要的。

回答by nhaarman

Add a callback interface, and let your Activityimplement it.

添加一个回调接口,让你Activity实现它。

public interface MyAsyncTaskCallback{
    public void onAsyncTaskComplete();
}

In the postexecute:

在后执行中:

myAsyncTaskCallback.onAsyncTaskComplete();

In the constructor of your AsyncTaskyou could pass the instance of MyAsyncTaskCallback(your Activity).

在您的构造函数中,您AsyncTask可以传递MyAsyncTaskCallback(your Activity)的实例。

回答by BrianPlummer

Your best way of handling this is via a Handler. Instantiate one in the activity and override the method handleMessage(). When you create ShowDialogAsyncTaskclass just pass in the handler and maintain a reference to it. On postExecuteyou can construct a message and send it via the handler method sendMessage().

处理此问题的最佳方法是通过 Handler。在活动中实例化一个并覆盖方法handleMessage()。当您创建ShowDialogAsyncTask类时,只需传入处理程序并维护对它的引用。在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 postExecutemethod is executed so you would need to test for this.

之前的答案提到使用接口和回调范例。这将起作用,但是,活动有可能被销毁并且在postExecute执行方法时不存在,因此您需要对此进行测试。