Я сделал две разные службы (по-разному перечисленные в манифесте), в которых есть две разные 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
спасибо за ваш комментарий ... Я поменял Сервис на класс IntentService .. но не могу понять, куда я должен помещать коды текущего метода onDestroy. Если вы plz помогите ... – abdfahim
Сначала, когда ваш IntentService остановится сам по себе, вы можете удалить свой вызов на 'MyServiceClass.this.stopSelf()'. Во-вторых, я бы рекомендовал вам реализовать 'onHandleIntent', если вам нужно проверить новые параметры Intent. Наконец, я не понимаю, почему вы должны изменить свой код 'onDestroy', не вызван ли он? – zozelfelfo
(извините, что сегодня ужасный интернет, откладывается) .. в любом случае, да, действительно. OnDestroy вызывается до PostExecute (из AsyncTask)! Я обновил свой пост, чтобы дать свой последний код и logcat, если вы любезно проверяете .. и он несовместим (иногда называемый сразу после PREEXECUTE !!) – abdfahim