android - 可以在AsyncTask中重载publishProgress吗?

标签 android android-asynctask

我正在尝试在后台进程中发布两种不同类型的进度。我试图有时发布一个字符串,有时发布一个整数。我也通过重载来处理 onProgressUpdate 中的两种参数。但是,当我声明 AsyncTask 类时,我有参数,这就是为什么它期望我仅发送字符串类型参数。有没有办法处理这两种类型的publishProgress事件?

最佳答案

基本上有两种方法可以解决您的问题:

第一个非常简单,您只需 publishUpdate(String) 即可,然后在 onProgressUpdate(String) 中检查字符串是 int 还是 a字符串,并以不同的方式处理每种情况,如下所示:

private class MyAsyncTask extends AsyncTask<Void, String, Void> {
    //Executed on main UI thread.
    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values); 
        try{
            Integer i = Integer.parseInt(values[0]);
            TextView v1 = (TextView) findViewById(R.id.textView1);
            v1.setText(String.valueOf(i));
        }
        catch(NumberFormatException e){
            TextView v2 = (TextView) findViewById(R.id.textView3);
            v2.setText(values[0]);
        }
    }
    @Override
    protected Void doInBackground(Void... params) {
        int i = 0;
        while(i < 100){
            try {
                if(i%2 == 0){
                    publishProgress("Divisible by 2: " + String.valueOf(i));
                }
                publishProgress(String.valueOf(i));
                i++;
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }   
        return null;
    }
}

在上面的示例中,我只是尝试将字符串解析为 Integer - 如果它有效,那么我 100% 确定它是一个 int - 如果它抛出异常,那么它就是一个 字符串

但是,如果您想要更多控制,则需要实现您自己的 AsyncTask 版本,该版本支持一个或多个进度更新。实现此目的的唯一方法是直接使用 Handlers ( http://developer.android.com/reference/android/os/Handler.html ) 和 Thread ( http://developer.android.com/reference/java/lang/Thread.html )(最好包装在类似于 AsyncTask 的更具逻辑性的类中) :

import android.os.Handler;
import android.os.Looper;

public abstract class DIYAsyncTask<Params, IntProgress, StringProgress, Result> {

    private Result backGroundResult;

    //Run on UI thread
    @SuppressWarnings("unchecked")
    protected void execute(Params... params){
        final Params[] thisParams = params;
        Thread worker = new Thread(){
            public void run(){
                prepareForPreExecute();
                backGroundResult = doInBackground(thisParams);
                prepareForPostExecute();
            }
        };
        worker.setPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
        worker.start();
    }

    //Code to start onPreExecute on UI thread
    private void prepareForPreExecute(){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        ui_handler.post(
                new Runnable(){
                    public void run(){
                        onPreExecute();
                    }
                }
            );
    }

    //Code to start onPostExecute on UI thread
    private void prepareForPostExecute(){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        ui_handler.post(
                new Runnable(){
                    public void run(){
                        onPostExecute(backGroundResult);
                    }
                }
            );
    }

    //Always run on worker thread
    @SuppressWarnings("unchecked")
    protected abstract Result doInBackground(Params... params);

    //Always run on UI
    protected void onPreExecute(){
    }

    //Always run on UI
    protected void onPostExecute(Result result){
    }

    //Run on worker
    @SuppressWarnings("unchecked")
    protected void publishIntProgress(IntProgress... values){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        final IntProgress[] thisProgress = values;
        ui_handler.post(
                new Runnable(){
                    @Override
                    public void run(){
                        onIntProgressUpdate(thisProgress);
                    }
                }
        );
    }

    //Always run on UI
    @SuppressWarnings("unchecked")
    protected void onIntProgressUpdate(IntProgress... values){

    }

    //Run on worker
    @SuppressWarnings("unchecked")
    protected void publishStringProgress(StringProgress... values){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        final StringProgress[] thisProgress = values;
        ui_handler.post(
                new Runnable(){
                    @Override
                    public void run(){
                        onStringProgressUpdate(thisProgress);
                    }
                }
        );
    }

    //Always run on UI
    @SuppressWarnings("unchecked")
    protected void onStringProgressUpdate(StringProgress... values){

    }
}

然后您可以像这样覆盖它(注意与仅使用 AsyncTask 的相似之处)

private class MyDIYAsyncTask extends DIYAsyncTask<Void, Integer, String, Void> {

    //Executed on main UI thread.
    @Override
    protected void onIntProgressUpdate(Integer... values) {
        super.onIntProgressUpdate(values); 
        TextView v = (TextView) findViewById(R.id.textView1);
        v.setText(String.valueOf(values[0]));
    }

    @Override
    protected void onStringProgressUpdate(String... values) {
        super.onStringProgressUpdate(values);
        TextView v = (TextView) findViewById(R.id.textView3);
        v.setText(values[0]);
    }

    @Override
    protected Void doInBackground(Void... params) {

        int i = 0;
        while(i < 100){
            try {
                publishIntProgress(i);
                publishStringProgress("MyString" + String.valueOf(i));
                i++;
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

}

关于android - 可以在AsyncTask中重载publishProgress吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23251315/

相关文章:

android - 从视频列表中获取youtube视频ID

java - 如何用 RXJava 替换 Thread.sleep()

java - 圆形布局 : Cannot resolve method onCreate(android. os.Bundle)

android - Android 登录中的 Soap Web 服务

Java : Subclassing AsyncTask

java - 如何在ubuntu 16.04中设置ANDROID_HOME环境变量

java - 如何在android中读取xml文件?

android - 如何使用暴力取消 AsyncTask

android - 关闭 Activity 时如何停止 Activity 的线程和套接字

android - 如何避免在一项 Activity 中执行多个异步任务