我没有花太多时间使用 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 个重要部分:
请记住,以上任何一个都可能是接口(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 任务,那么您需要考虑上述 myBgTask1和 myBgTask2调用将按顺序进行。如果一个调用依赖于另一个调用,这很好,但如果调用是独立的 - 例如,您正在下载多个图像,并且您不关心哪个先到达 - 那么您可以制作 myBgTask1和 myBgTask2与 THREAD_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/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解