可以在AsyncTask中重载publishProgress吗? [英] Can publishProgress be overloaded in AsyncTask?

查看:96
本文介绍了可以在AsyncTask中重载publishProgress吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to publish two different kinds of progress in my background process. I am trying to publish a string sometime and an integer another time. I am handling both kinds of arguments in the onProgressUpdate by overloading them too. But when I declare my AsyncTask class, I have the arguments that is why it is expecting me to send only string type arguments. Is there a way to handle both type of publishProgress events?

推荐答案

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

Basically there are two ways to address your issue:

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

The first one is very simple, where you just always publishUpdate(String), and then in your onProgressUpdate(String) checks whether the string is an int or a string, and handle each case differently like this:

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-如果它引发异常,则它是一个String.

In the above example I just try and parse the string to an Integer - if it works then I am 100% sure it is an int - if it throws an exception then it is a String.

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

If you want more control however, you need to implement your own version of AsyncTask, that support one or more progress updates. The only way you can achieve this is by using Handlers (http://developer.android.com/reference/android/os/Handler.html) and Thread (http://developer.android.com/reference/java/lang/Thread.html) directly (preferably wrapped in a more logical class similar to 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相似)

Which you can then override like this (notice the similarity to just using 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;
    }

}

这篇关于可以在AsyncTask中重载publishProgress吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆