我从网址获取信息并将该信息发送到多个网址。我在AsyncTask中的“for”上运行它,但事实是如果其他操作没有返回错误或成功,它就不会继续。所以我想在AsyncTask-ception中做到这一点,但遗憾的是Android并没有让我这么做。
所以,我有两个AsyncTask类。那是我发给网站的课程:
let Language = getWindowsType @"Windows.Globalization.Language"
let OcrEngine = getWindowsType "Windows.Media.Ocr.OcrEngine"
let BitmapDecoder = getWindowsType "Windows.Graphics.Imaging.BitmapDecoder"
let StorageFile = getWindowsType "Windows.Storage.StorageFile"
let enUs = Language.GetConstructor([|typeof<string>|]).Invoke([|"en-US"|])
let engine : obj = OcrEngine?TryCreateFromLanguage enUs
let getTextAsync (path:string) : Async<string> = async {
let! file = StorageFile?GetFileFromPathAsync path
let! stream = file?OpenReadAsync()
let! decoder = BitmapDecoder?CreateAsync stream
let! bitmap = decoder?GetSoftwareBitmapAsync()
let! result = engine?RecognizeAsync bitmap
return result?Text
}
这是我从网站获得的任务:
class SendTo extends AsyncTask <Object,Object,String>{
@Override
protected String doInBackground(Object... strings) {
....
}
}
但遗憾的是我在AS上遇到了这些错误:
必须从当前推断的主线程调用方法execute 线程是工作者
非静态方法'execute(Params ...)'不能从a引用 静态上下文
您是否有任何想法或解决方案或方法来实现这一目标?谢谢你的帮助。
答案 0 :(得分:0)
正如您在一些评论和您看到的异常中所指出的那样,您无法从任意线程上下文(例如另一个AsyncTask
的{{1}}方法启动doInBackground()
。而不是立即启动它们,收集您的AsyncTask
&#34;参数以发送&#34;到数组或String
并从Set
方法返回。然后,在您的{ {1}}返回值的方法将作为参数提供。遍历数组中的每个条目或doInBackground()
并触发新的onPostExecute()
来处理该事务。
如果您希望它们并行运行,请使用备用Set
作为AsyncTask
,否则它们将以串行方式运行。
您也可以使用自己的executeOnExecutor
来完成类似的操作,这可以通过创建大量AsyncTask
个对象来减少堆栈崩溃,因为它们是一次性使用。
答案 1 :(得分:0)
您的第一个错误:Method execute must be called from the main thread, currently inferred thread is worker
是因为您从第一项任务AsyncTask
开始拨打第二个doInBackground()
。 doInBackground()
是一个工作线程,你不能从后台线程执行另一个任务,它必须来自UI
线程。 AsyncTask
用于简短操作,如果您需要更复杂的操作,则考虑使用Thread
。
您的第二个错误:Non-static method 'execute(Params...)' cannot be referenced from a static context
是因为您正在调用AsyncTask
,就好像它是静态的而不是实例一样。您对new SendTo.execute(websites[i], param)
的调用似乎没问题,除非您不能有2个参数,execute()
的参数作为数组传入
我建议的是,对于看似相似的请求而不是有2个单独的任务,而是要有1个任务,并添加一个标志来定义您想要执行的操作类型。 (SEND或FETCH)然后在doInBackground()
检查标志并执行指定的操作。您似乎正在发送数据,然后尝试检索响应,因此当您的SEND操作完成后,添加一个您想要检索该数据的辅助标记,并在onPostExecute()
重新运行您的任务对于其他操作。
答案 2 :(得分:-1)
我假设您要开始AsyncTask
并行地在后台执行某些操作。
为此,请不要使用嵌套的AsyncTask
,而是应该使用ExecutorService
,将任务提交到此类工作池,收集结果,从异步任务返回。
有些详细信息位于适用于Android的ExecutorService文档中