如何进出AsyncTasks的传递变量? [英] How to pass variables in and out of AsyncTasks?

查看:131
本文介绍了如何进出AsyncTasks的传递变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有花很多时间在Android的AsyncTasks工作。我想了解如何将变量传递给和从类。这里的语法:​​

I haven't spent much time working with AsyncTasks in Android. I'm trying to understand how to pass variables to and from the class. The syntax here:

class MyTask extends AsyncTask<String, Void, Bitmap>
{

}

这是一个有点混乱与&LT; &GT; 的类定义的结束语法。以前从未见过这种类型的语法。好像我是仅限于传递一个值到AsyncTask的。我是不正确的假设呢?如果我有更多的传球,我该怎么办呢?

it's a little bit confusing with the < > syntax on the end of the class definition. Never seen that type of syntax before. It seems like I'm limited to only passing one value into the AsyncTask. Am I incorrect in assuming this? If I have more to pass, how do I do that?

另外,我怎么返回值从AsyncTask的?这是一个一流的,当你想使用它,你调用新MyTask的()。执行()但你在课堂上使用的实际方法是 doInBackground ()。那么,你真的返回的东西?

Also, how do I return values from the AsyncTask? It's a class and when you want to use it you call new MyTask().execute() but the actual method you use in the class is doInBackground(). So where do you actually return something?

推荐答案

注:以下所有的信息可以在Android开发的 <一个href="http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor%28java.util.concurrent.Executor,%20Params...%29">AsyncTask参考页 。在用法头有一个例子。另外看看在 无痛线程Android开发者博客条目

Note: all of the information below is available on the Android Developers AsyncTask reference page. The Usage header has an example. Also take a look at the Painless Threading Android Developers Blog Entry.

看看<一href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java">the来源$ C ​​$下AsynTask

有趣&LT; &GT; 标记可以让你定制你的异步任务。括号是用来帮助实现 在Java泛型

The funny < > notation lets you customize your Async task. The brackets are used to help implement generics in Java.

有一个任务,你可以自定义3个重要部分:

There are 3 important parts of a task you can customize:

  1. 在传递的参数的类型 - 你想要的任何数量
  2. 你用它来更新什么类型的进度条/指示灯
  3. 为你回到曾经的后台任务所做的工作

和记住,上述任何可能的接口。这就是你如何能够通过多种类型的同一来电!

And remember, that any of the above may be interfaces. This is how you can pass in multiple types on the same call!

您把这些东西3中的类型尖括号:

You place the types of these 3 things in the angle brackets:

<Params, Progress, Result>

所以,如果你要传递网​​址和使用整数更新进度,并返回一个布尔值,指示成功,你会写:

So if you are going to pass in URLs and use Integers to update progress and return a Boolean indicating success you would write:

public MyClass extends AsyncTask<URL, Integer, Boolean> {

在这种情况下,如果你是下载位图,例如,你会处理你做什么用位图的背景。你也可以只返回位图的一个HashMap,如果你想要的。还记得你使用没有限制的成员变量,所以并不觉得太束缚随参数,进度和结果。

In this case, if you are downloading Bitmaps for example, you would be handling what you do with the Bitmaps in the background. You could also just return a HashMap of Bitmaps if you wanted. Also remember the member variables you use are not restricted, so don't feel too tied down by params, progress, and result.

要启动一个AsyncTask的实例,然后执行,要么按顺序或并行。在执行是你传递的变量。可以通过在一个以上的

To launch an AsyncTask instantiate it, and then execute it either sequentially or in parallel. In the execution is where you pass in your variables. You can pass in more than one.

请注意,您的不叫 doInBackground() 直接。这是因为这样做会破坏​​AsyncTask的,这是 doInBackground()在后台线程中完成的魔力。直接作为呼唤它,将使它在UI线程中运行。所以,相反,你应该使用的形式执行()的任务执行()是揭开序幕 doInBackground()在后台线程,而不是UI线程。

Note that you do not call doInBackground() directly. This is because doing so would break the magic of the AsyncTask, which is that doInBackground() is done in a background thread. Calling it directly as is, would make it run in the UI thread. So, instead you should use a form of execute(). The job of execute() is to kick off the doInBackground() in a background thread and not the UI thread.

我们从上面的例子中工作。

Working with our example from above.

...
myBgTask = new MyClass();
myBgTask.execute(url1, url2, url3, url4);
...

onPostExecute 将触发时,从执行的所有任务都做了。

onPostExecute will fire when all the tasks from execute are done.

myBgTask1 = new MyClass().execute(url1, url2);
myBgTask2 = new MyClass().execute(urlThis, urlThat);

请注意,你如何将多个参数传递给执行()这传递多个参数上 doInBackground() 。这是通过使用<一href="http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html">varargs (你知道像的String.Format(...)。许多例子只能使用显示第一个PARAMS提取PARAMS [0] ,但你应该 <一个href="http://www.java2s.com/$c$c/Java/Language-Basics/JavavarargsIteratingOverVariableLengthArgumentLists.htm">make确保你得到所有PARAMS 如果您通过本会的网址(取自AsynTask例如,有多种方法可以做到这一点)。

Notice how you can pass multiple parameters to execute() which passes the multiple parameter on to doInBackground(). This is through the use of varargs (you know like String.format(...). Many examples only show the extraction of the first params by using params[0], but you should make sure you get all the params. If you are passing in URLs this would be (taken from the AsynTask example, there are multiple ways to do this):

 // This method is not called directly. 
 // It is fired through the use of execute()
 // It returns the third type in the brackets <...>
 // and it is passed the first type in the brackets <...>
 // and it can use the second type in the brackets <...> to track progress
 protected Long doInBackground(URL... urls) 
 {
         int count = urls.length;
         long totalSize = 0;

         // This will download stuff from each URL passed in
         for (int i = 0; i < count; i++) 
         {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
         }

         // This will return once when all the URLs for this AsyncTask instance
         // have been downloaded
         return totalSize;
 }

如果你打算做多BG的任务,那么你要考虑的是,上述 myBgTask1 myBgTask2 通话将被制成依次。这是伟大的,如果一个呼叫依赖于其他,但如果调用独立的 - 比如你正在下载多个图像,并且不关心哪一个先到 - 那么你可以让 myBgTask1 myBgTask2 与并行调用 THREAD_POOL_EXECUTOR

If you are going to be doing multiple bg tasks, then you want to consider that the above myBgTask1 and myBgTask2 calls will be made in sequence. This is great if one call depends on the other, but if the calls are independent - for example you are downloading multiple images, and you don't care which ones arrive first - then you can make the myBgTask1 and myBgTask2 calls in parallel with the THREAD_POOL_EXECUTOR:

myBgTask1 = new MyClass().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url1, url2);
myBgTask2 = new MyClass().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urlThis, urlThat);


注意:

示例

下面是一个例子AsyncTask的,只要你想在同一执行()命令,可以采取多种类型。该限制是每个类型都必须实现相同的接口:

Here is an example AsyncTask that can take as many types as you want on the same execute() command. The restriction is that each type must implement the same interface:

public class BackgroundTask extends AsyncTask<BackgroundTodo, Void, Void>
{
    public static interface BackgroundTodo
    {
        public void run();
    }

    @Override
    protected Void doInBackground(BackgroundTodo... todos)
    {
        for (BackgroundTodo backgroundTodo : todos)
        {
            backgroundTodo.run();

            // This logging is just for fun, to see that they really are different types
            Log.d("BG_TASKS", "Bg task done on type: " + backgroundTodo.getClass().toString());
        }
        return null;
    }
}

现在,你可以这样做:

new BackgroundTask().execute(this1, that1, other1); 

每个地方的对象是不同类型的! (实现相同的接口)

Where each of those objects is a different type! (which implements the same interface)

这篇关于如何进出AsyncTasks的传递变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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