CheckAutoSyncSendingOrder

CheckAutoSyncSendingOrder

本文介绍了服务自动调用摧毁活动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我坚持的 活动+服务 的问题,即我有以下活动和服务的数量。

活动:

Services:

  1. ReceivingOrderService - Receiving New Data From Server
  2. SendingOrderService - Sending new Data to Server

Above both Service Calling from another Separate Service on duration of some interval.

  1. CheckAutoSyncReceivingOrder - To call ReceivingOrderService (Interval 15Mins)
  2. CheckAutoSyncSendingOrder - To call SendingOrderService (Interval 3Mins)

CheckAutoSyncReceivingOrder:

public class CheckAutoSyncReceivingOrder extends Service {

    Timer timer;

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

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub

        if(timer != null) {
            timer.cancel();
            Log.i(TAG, "RECEIVING OLD TIMER CANCELLED>>>");
        }

        timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if(InternetConnection.checkConnection(getApplicationContext())) {
                    if(getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                        startService(new Intent(CheckAutoSyncReceivingOrder.this, ReceivingOrderService.class));
                } else {
                    Log.d(TAG, "Connection not available");
                }
            }
        }, 0, 60000); // 1000*60*15 = 9,00,000 = 15 minutes
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();

        if(timer != null)
            timer.cancel();

        Log.d(TAG, "Stopping Receiving...");
    }
}

CheckAutoSyncSendingOrder:

public class CheckAutoSyncSendingOrder extends Service {

    Timer timer;

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

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub

        if(timer != null) {
            timer.cancel();
            Log.i(TAG, "OLD TIMER CANCELLED>>>");
        }

        timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(TAG, ">>>>>>>> SENDING AUTO SYNC SERVICE >>>>>>>>");
                if(InternetConnection.checkConnection(getApplicationContext())) {
                    if(getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                        startService(new Intent(CheckAutoSyncSendingOrder.this, SendingOrderService.class));
                } else {
                    Log.d(TAG, "connection not available");
                }
            }
        }, 0, 120000); //  1000*120*15 = 1,800,000 = 15 minutes
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();

        if(timer != null)
            timer.cancel();

        Log.d(TAG, "Stopping Sending...");
    }
}

ConfirmOrderActivity#Final Task which i have called for Insert Data:

new AsyncTask<Void, Void, Integer>() {

    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();

        progressDialog = new ProgressDialog(
                ConfirmOrderProductActivity.this);
        progressDialog.setMessage("Inserting "
                + (isInquiry ? "Inquiry" : "Order") + "...");
        progressDialog.setCancelable(false);
        progressDialog
                .setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.show();
    }

    @Override
    protected Integer doInBackground(Void... params) {
        // TODO Auto-generated method stub
        int account_id = context.getSharedPreferences(PREF_DATA,
                MODE_APPEND).getInt(DATA_ACCOUNT_ID, 0);

        /**
         * Check Whether isInquiry or not...
         */
        product_type = isWeight ? 1 : 0;
        if (isInquiry) {
            /*
             * INSERTING DATA IN INQUIRY TABLE
             */
            return m_inquiry_id;
        } else {
            /*
             * INSERTING DATA IN ORDER TABLE
             */
            return m_order_id;
        }
    }

    @Override
    protected void onPostExecute(Integer m_order_id) {
        // TODO Auto-generated method stub
        super.onPostExecute(m_order_id);

        progressDialog.dismiss();

        if (dbHelper.db.isOpen())
            dbHelper.close();

        String title = "Retry";
        String message = "There is some problem, Go Back and Try Again";

        AlertDialog.Builder alert = new AlertDialog.Builder(
                ConfirmOrderProductActivity.this);

        if (m_order_id != -1) {
            title = isInquiry ? "New Inquiry" : "New Order";
            message = isInquiry ? "Your Inquiry Send Successfully." : "Your Order Saved Successfully.";
            alert.setIcon(R.drawable.success).setCancelable(false);
        } else {
            alert.setIcon(R.drawable.fail).setCancelable(false);
        }

        alert.setTitle(title).setMessage(message)
                .setPositiveButton("OK", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog,
                            int which) {
                        // TODO Auto-generated method stub
                        dialog.dismiss();
                        startActivity(new Intent(
                                ConfirmOrderProductActivity.this,
                                FragmentChangeActivity.class)
                                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));

                        /* Opening Left to Right Animation */
                        overridePendingTransition(R.anim.right_out,
                                R.anim.right_in);
                    }
                });

        AlertDialog alertDialog = alert.create();
        alertDialog.show();

    }
}.execute();

Everything is working fine as per flow of inserting records in database.

After Adding Inquiry:

Destroying Activity and Getting following Logcat:

Main Problem:

When I placed order successfully from ConfirmOrderActivity, It is displaying AlertDialog of Success Message which is cancellable false. When I Stop application from this Activity, Its calling both CheckAutoSyncReceivingOrder and CheckAutoSyncSendingOrder automatically.

Edited:

I didn't know why it happens that Why its running automatically when I stop Activity Directly.

I have tried onStartCommand() with START_NON_STICKY in Service but not working. (as START_STICKY is default.)

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}

Is there any solution?

解决方案

You need to either run your service in the foreground so when the activity is destroyed so will the service or use a bound service and manage the binding with the activity lifecycle, so it is not continually restarted when the activity is destroyed.

From this android docs tutorial Bound Services

You need to do this for each service.

public class CheckAutoSyncReceivingOrder extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        CheckAutoSyncReceivingOrder getService() {
        return CheckAutoSyncReceivingOrder.this;
    }
}

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

From your activity that creates and calls the service, that when it is destroyed you want your service destroyed.

public class BindingActivity extends Activity {
    CheckAutoSyncReceivingOr mService;
    boolean mBound = false;


    @Override
    protected void onStart() {
        super.onStart();
        // Bind to CheckAutoSyncReceivingOr
        Intent intent = new Intent(this, CheckAutoSyncReceivingOr.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
            IBinder service) {
            // We've bound to CheckAutoSyncReceivingOr, cast the IBinder and get CheckAutoSyncReceivingOr instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
}

And manage the service lifecycle. Restart the same service with your timer, do not create a new service.

public class ExampleService extends Service {
    int mStartMode;       // indicates how to behave if the service is killed
    IBinder mBinder;      // interface for clients that bind
    boolean mAllowRebind; // indicates whether onRebind should be used

    @Override
    public void onCreate() {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return mStartMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy() {
        // The service is no longer used and is being destroyed
    }
}

Note START_NOT_STICKY will only prevent the service from restarting if the device is low on memory.

Be mindful that you where you are starting services, just start it once and allow the service to maintain it's own lifecycle until you destroy it with your activity.

This is in reply to your original unedited question, when the app was mysteriously crashing:

You need to destroy the dialog before the context window the dialog is attached to. That will cause a problem. So this is where program flow and the order of closing and cleaning up resources is important. They, frequently have to be destroyed in the reverse order they were created if they are dependent upon parent windows (which is often in the form of a particular activity).

It's difficult to trace your code, so this is a generic answer.

Make use of onPause and onDestroy in your activities.

In all your activities, manage any resources you have created within that activity and with a null check, close them down. Like you have in your service class. If you want to override the parent onDestroy, place your custom code before super.onDestroy.

protected void onDestroy() {

    if(timer != null)
        timer.cancel();

    Log.d(TAG, "Stopping Sending...");

    super.onDestroy();
}

这篇关于服务自动调用摧毁活动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 03:34