2014-01-03 2 views
1

Я сделал две разные службы (по-разному перечисленные в манифесте), в которых есть две разные AsyncTask. Я запускаю их из двух разных фрагментов (то же самое действие).Услуги не выполняются параллельно

Но если я запускаю их одновременно, одна услуга будет поставлена ​​в очередь до завершения другой службы. Когда у меня были эти AsyncTask внутри фрагмента напрямую (без использования службы), я мог бы запускать их параллельно.

В любом случае я могу запускать их параллельно с помощью службы?

Спасибо,

Код каждого класса обслуживания аналогичен:

public class MyServiceClass extends Service{ 

    public boolean isCancelled = false; 
    DownloadFile downloadFile; 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction("com.example.STOP"); 
     registerReceiver(receiver, filter); 
     downloadFile = new DownloadFile(); 
     downloadFile.execute(); 
     return 0; 
    } 

    private final BroadcastReceiver receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      if(action.equals("com.example.STOP")){ 
       isCancelled = true; 
      } 

     } 
    }; 

    @Override 
    public void onDestroy() { 
     unregisterReceiver(receiver); 
     if (downloadFile != null && downloadFile.getStatus() != AsyncTask.Status.FINISHED){ 
      downloadFile.cancel(true); 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    private class DownloadFile extends AsyncTask<Void, String, String> 
    { 
     NotificationManager mNotifyManager; 
     NotificationCompat.Builder mBuilder; 
     int mId = 2; 
     Context context; 

     @Override 
     protected void onPreExecute() { 
      context = getApplicationContext(); 
      if(context!=null){ 
       Intent newintent = new Intent(); 
       newintent.setAction("com.example.STOP"); 
       PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, newintent, 0); 
       mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
       mBuilder = new NotificationCompat.Builder(context); 
       mBuilder.setContentTitle("Cover Download") 
        .setContentText("In progress") 
        .setContentIntent(pIntent) 
        .setSmallIcon(R.drawable.ic_launcher); 
      } 
     } 

     @Override 
     protected String doInBackground(Void... args) { 
       DOING TASKS 
     } 

     @Override 
     protected void onProgressUpdate(String... values) 
     { 
      Toast.makeText(context, values[0], Toast.LENGTH_LONG).show(); 
     } 

     @Override 
     protected void onPostExecute(String result1) 
     { 
      mBuilder.setContentText(result1).setProgress(0,0,false); 
      mNotifyManager.notify(mId, mBuilder.build()); 
      context = null; 
      MyServiceClass.this.stopSelf(); 
     } 
    } 
} 

EDITED КОДА С ИСПОЛЬЗОВАНИЕМ INTENTSERVICE

public class MyImportServiceClass extends IntentService{ 

    public MyImportServiceClass() { 
     super("MyImportServiceClass"); 
    } 

    RemoteConnectivity importExport; 
    String code; 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     Log.d("CHECKPOINT","INTENT START"); 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction("com.example.MyImportServiceClass.STOPIMEX"); 
     String data = intent.getStringExtra("data"); 
     code = intent.getStringExtra("code"); 
     registerReceiver(imreceiver, filter); // TO CANCEL ASYNCTASK WHEN USER CLICK ON NOTIFICATION 


importExport = new RemoteConnectivity(); 
     importExport.execute(code,data); 
    } 

    private final BroadcastReceiver imreceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      if(action.equals("com.example.MyImportServiceClass.STOPIMEX")){ 
       if (importExport != null && importExport.getStatus() != AsyncTask.Status.FINISHED){ 
        importExport.cancel(true); 
       } 
      } 

     } 
    }; 

    @Override 
    public void onDestroy() { 
     Log.d("CHECKPOINT","DESTROY"); 
     unregisterReceiver(imreceiver); 
     if(code.equals("1") || code.equals("2") || code.equals("6")){ 
      Log.d("CHECKPOINT","DESTROY ANNOUNCE TO MAIN THREAD"); 
      Intent intent = new Intent(); 
      intent.setAction("com.example.MyImportServiceClass.UPDATE"); 
      LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 
     } 

    } 

    private class RemoteConnectivity extends AsyncTask<String, String, String> 
    { 
     NotificationManager mNotifyManager; 
     NotificationCompat.Builder mBuilder; 
     int mId; 
     Context context; 
     @Override 
     protected void onPreExecute() { 
      Log.d("CHECKPOINT","PREEXECUTE"); 
      context = getApplicationContext(); 
      Intent newintent = new Intent(); 
      newintent.setAction("com.example.MyImportServiceClass.STOPIMEX"); 
      PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, newintent, 0); 

      mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
      mBuilder = new NotificationCompat.Builder(context); 
      mBuilder.setContentTitle("Import/Export") 
        .setContentText("In progress") 
        .setContentIntent(pIntent) 
        .setSmallIcon(R.drawable.ic_launcher); 
      } 
     } 

     @Override 
     protected String doInBackground(String... args) { 
      Log.d("CHECKPOINT","START BACKGROUND"); 
      ............. 
      ............. 
      Log.d("FLAGPOINT","IMPORTING"); 
      mylibmandbhandler db = new mylibmandbhandler(context); 
      while ((line = br.readLine()) != null) { 
         //DOING THINGS 
       if(isCancelled){ 
        db.close(); 
        return null; 
       } 
      } 
      db.close(); 
      return "done"; 
     } 

     @Override 
     protected void onPostExecute(String result1) 
     { 
      Log.d("CHECKPOINT","COMPLETED"); 

     } 

     @Override 
     protected void onCancelled(){ 
      Log.d("CHECKPOINT","CANCELLED"); 

     } 
    } 
} 

LogCat

01-03 06:49:36.367: D/CHECKPOINT(2019): INTENT START 
01-03 06:49:36.387: D/CHECKPOINT(2019): PREEXECUTE 
01-03 06:49:36.397: D/CHECKPOINT(2019): START BACKGROUND 
01-03 06:49:36.457: D/CHECKPOINT(2019): DESTROY 
01-03 06:49:36.457: D/CHECKPOINT(2019): ANNOUNCE 
01-03 06:49:36.997: D/FLAGPOINT(2019): IMPORTING 

ответ

1

Услуги выполняются в потоке пользовательского интерфейса, поэтому ОС решит, какая служба будет первой и когда она будет остановлена. Если бы я был вами, я бы изменил классы обслуживания для IntentService, поскольку у них есть собственный рабочий поток. Я думаю, что это будет полезно, чтобы заставить их работать одновременно.

+0

спасибо за ваш комментарий ... Я поменял Сервис на класс IntentService .. но не могу понять, куда я должен помещать коды текущего метода onDestroy. Если вы plz помогите ... – abdfahim

+1

Сначала, когда ваш IntentService остановится сам по себе, вы можете удалить свой вызов на 'MyServiceClass.this.stopSelf()'. Во-вторых, я бы рекомендовал вам реализовать 'onHandleIntent', если вам нужно проверить новые параметры Intent. Наконец, я не понимаю, почему вы должны изменить свой код 'onDestroy', не вызван ли он? – zozelfelfo

+0

(извините, что сегодня ужасный интернет, откладывается) .. в любом случае, да, действительно. OnDestroy вызывается до PostExecute (из AsyncTask)! Я обновил свой пост, чтобы дать свой последний код и logcat, если вы любезно проверяете .. и он несовместим (иногда называемый сразу после PREEXECUTE !!) – abdfahim

Смежные вопросы