在Asynctask中运行多个线程

时间:2016-08-18 19:32:07

标签: java android multithreading android-asynctask

我从网址获取信息并将该信息发送到多个网址。我在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引用   静态上下文

您是否有任何想法或解决方案或方法来实现这一目标?谢谢你的帮助。

3 个答案:

答案 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文档中