简体   繁体   English

Android排队后台线程

[英]Android enqueue background threads

I have a loop where some objects are created and I need a thread to handle that objects. 我有一个循环,其中创建了一些对象,并且需要一个线程来处理这些对象。 For now I get OOM error because all threads are started at the same time. 现在,我收到OOM错误,因为所有线程同时启动。

for (final String filePath : myFilesList) {
      obj1= ...
      obj2= ...

      tryUploadFile(obj1, obj2);
}


private void tryUploadFile(final Object obj1, final Object obj2) {
    new Thread() {
        @Override
        public void run() {
           //handle obj1 & obj2 (upload to Google Drive file)
        }
    }.start();
}

I need to have it in queue, so when first thread finish start second one and so on. 我需要将它放在队列中,因此当第一个线程完成时再启动第二个,依此类推。 I tried with IntentService , because it runs only one instance at a time but I can't send params to IntentService excepting primitive extras. 我尝试使用IntentService ,因为它一次只运行一个实例,但是除了原始附加功能外,我无法将参数发送给IntentService Any help is apreciated. 任何帮助都非常感谢。

Don't create a thread everytime in a loop, instead of that use a single thread such as AsyncTask and others, Still if you want a seperate thread for each upload operation then wait first to finish, 不要每次都在循环中创建一个线程,而不要使用一个线程(例如AsyncTask和其他线程),但是,如果您希望为每个上载操作使用单独的线程,请先等待,

Approach 1 Using single thread and uploading sequentially, 方法1:使用单线程并按顺序上传,

private void tryUploadFile(final List<Object> myFilesList) {
    new AsyncTask<Void, Void, Void>() {
          @Override
          protected Long doInBackground() {
for (final Object filePath : myFilesList) {
      obj1 = ...
      obj2 = ...

      // handle obj1 & obj2
}          return null;
      }
    }.execute();
}

Approach 2 Create a thread for every request but sequentially. 方法2为每个请求创建一个线程,但顺序执行。

tryUploadFile(myFilesList.get(0), myFilesList.get(1)); // using index 0 & 1 for obj1 & obj2 change accordingly.

private void tryUploadFile(final Object obj1, final Object obj2) {
    new AsyncTask<Void, Void, Void>() {
          @Override
          protected Long doInBackground() {
      // handle obj1 & obj2
      obj1 = ...
      obj2 = ...

}          return null;
      }
    @Override
    protected void onPostExecute() {
    // Remove the uploaded value from the existing list.
    mMyFilesList.remove(yourPosition); // Obj1
    mMyFilesList.remove(yourPosition); // obj2

// recursive call to same method until the size of list is >0.
tryUploadFile (mMyFilesList.get(yourUpdatedPosition), mMyFilesList.get(yourUpdatedPosition));
      }
    }.execute();
}

Don't create those many threads. 不要创建那么多线程。 Wrap your thread logic in a Runnable class and submit the tasks to ThreadPoolExecutor 将线程逻辑包装在Runnable类中,然后将任务提交给ThreadPoolExecutor

Code snippet: 程式码片段:

class UploadTask implements Runnable{
    Object obj1;
    Object obj2;
    public UploadTask(Object obj1,  Object obj2){
        this.obj1 = obj1;
        this.obj2 = obj2;
    }
    public void run(){
         //handle obj1 & obj2 (upload to Google Drive file)
    }
}



 BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
 ThreadPoolExecutor executor = new ThreadPoolExecutor(
        Runtime.getRuntime().availableProcessors(),       // Initial pool size
        Runtime.getRuntime().availableProcessors(),       // Max pool size
        1, // KEEP_ALIVE_TIME
        TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
        workQueue);

for (final String filePath : myFilesList) {
      obj1= ...
      obj2= ...

      UploadTask task = new UploadTask(obj1, obj2);
      executor.execute(task);
}

If you need to pass values back to UI Thread, post the Message on UI Thread Handler [ new Handler(Looper.getMainLooper() )] 如果需要将值传递回UI线程,请将消息发布到UI线程处理程序[ new Handler(Looper.getMainLooper() )]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM