gpt4 book ai didi

android - 如何将变量传入和传出 AsyncTasks?

转载 作者:IT老高 更新时间:2023-10-28 23:27:03 26 4
gpt4 key购买 nike

我没有花太多时间使用 AsyncTasks在安卓中。我试图了解如何将变量传入和传出类。语法:

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

// Your Async code will be here

}

它与 < > 有点混淆类定义末尾的语法。以前从未见过这种类型的语法。似乎我仅限于将一个值传递给 AsyncTask .我假设这个不正确吗?如果我还有更多要通过,我该怎么做?

另外,如何从 AsyncTask 返回值?

这是一个类,当你想使用它时,你调用 new MyTask().execute()但是你在类里面使用的实际方法是doInBackground() .那么你实际上在哪里返回东西呢?

最佳答案

注意:Android 开发者 AsyncTask reference page 上提供了以下所有信息Usage header 有一个示例。另请查看 Painless Threading Android Developers Blog Entry

看看the source code for AsynTask .


有趣的 < >表示法允许您自定义异步任务。括号用于帮助实现 generics in Java .

您可以自定义任务的 3 个重要部分:

  1. 传入的参数类型 - 任意数量
  2. 用于更新进度条/指示器的类型
  3. 后台任务完成后返回的类型

请记住,以上任何一个都可能是接口(interface)。这就是你可以在同一个调用中传递多种类型的方法!

你把这三个东西的类型放在尖括号里:

<Params, Progress, Result>

所以如果你要通过 URL s 并使用 Integers更新进度并返回一个表示成功的 bool 值:

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

在这种情况下,例如,如果您正在下载位图,您将在后台处理您对位图所做的事情。如果需要,您也可以只返回位图的 HashMap。还要记住你使用的成员变量是不受限制的,所以不要被参数、进度和结果束缚。

要启动 AsyncTask 实例化它,然后 execute它可以顺序或并行。在执行中是您传递变量的地方。你可以传入多个。

请注意,您不要调用doInBackground() 直接。这是因为这样做会破坏 AsyncTask 的魔力,即 doInBackground()在后台线程中完成。直接按原样调用它会使其在 UI 线程中运行。因此,您应该使用 execute() 的形式。 . execute()的工作是启动doInBackground()在后台线程而不是 UI 线程中。

使用上面的示例。

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

onPostExecute将在执行的所有任务完成后触发。

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

注意如何将多个参数传递给 execute()它将多个参数传递给 doInBackground() .这是通过使用 varargs (您知道 String.format(...) 。许多示例仅显示使用 params[0] 提取第一个参数,但您应该 make sure you get all the params 。如果您传入 URL,这将是(取自AsynTask 示例,有多种方法可以做到这一点):

 // 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 任务,那么您需要考虑上述 myBgTask1myBgTask2调用将按顺序进行。如果一个调用依赖于另一个调用,这很好,但如果调用是独立的 - 例如,您正在下载多个图像,并且您不关心哪个先到达 - 那么您可以制作 myBgTask1myBgTask2THREAD_POOL_EXECUTOR 并行调用:

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

注意:

示例

这是一个示例 AsyncTask,它可以在同一个 execute() 上采用任意数量的类型命令。限制是每种类型必须实现相同的接口(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); 

其中每个对象都是不同的类型! (实现相同的接口(interface))

关于android - 如何将变量传入和传出 AsyncTasks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9900834/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com