服务自动调用销毁活动

Pra*_*ani 13 android android-service android-activity android-intentservice

我遇到的问题是Activity + Service,我有以下数量的活动和服务.

活动内容:

LoginActivity => OrderListActivity => AddOrderActivity => ConfirmOrderActivity

服务:

  1. ReceivingOrderService - 从服务器接收新数据
  2. SendingOrderService - 将新数据发送到服务器

在某个间隔的持续时间内,来自另一个单独服务的服务呼叫.

  1. CheckAutoSyncReceivingOrder - 调用ReceivingOrderService(间隔15分钟)
  2. CheckAutoSyncSendingOrder - 调用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...");
    }
}
Run Code Online (Sandbox Code Playgroud)

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...");
    }
}
Run Code Online (Sandbox Code Playgroud)

我要求插入数据的ConfirmOrderActivity#Final Task:

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();
Run Code Online (Sandbox Code Playgroud)

根据在数据库中插入记录的流程,一切正常.

添加查询后:

在此输入图像描述

销毁活动并获取以下Logcat:

在此输入图像描述

主要问题:

当我从放置顺序成功ConfirmOrderActivity,它显示AlertDialog成功消息,其是可取消 false.当我从这个活动停止的应用程序,它的调用都CheckAutoSyncReceivingOrderCheckAutoSyncSendingOrder自动.

编辑:

LoginActivity只调用两个Service ,之后它会在给定的时间间隔后自动调用但是当我在显示对话框时销毁ConfirmOrderActivity时出现问题.

我不知道为什么它会在我直接停止Activity时自动运行.

我曾尝试onStartCommand()START_NON_STICKYService,但不工作.(START_STICKY默认情况下.)

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}
Run Code Online (Sandbox Code Playgroud)

有什么解决方案吗?

小智 4

您需要在前台运行服务,以便当活动被销毁时,服务也会运行,或者使用绑定服务并管理与活动生命周期的绑定,这样当活动被销毁时,它不会不断重新启动。

从这个 android 文档教程绑定服务

您需要为每项服务执行此操作。

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;
    }   
Run Code Online (Sandbox Code Playgroud)

从创建和调用服务的活动来看,当它被销毁时,您希望您的服务被销毁。

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;
        }
    };
}   
Run Code Online (Sandbox Code Playgroud)

并管理服务生命周期。使用计时器重新启动相同的服务,不要创建新服务。

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
    }
}
Run Code Online (Sandbox Code Playgroud)

START_NOT_STICKY仅当设备内存不足时,“注释”才会阻止服务重新启动。

请注意,您在启动服务的位置,只需启动一次,并允许服务维护其自己的生命周期,直到您通过活动销毁它。

这是对您最初未经编辑的问题的答复,当应用程序神秘崩溃时:

您需要在对话框附加到的上下文窗口之前销毁该对话框。这会导致一个问题。因此,这就是程序流程以及关闭和清理资源的顺序很重要的地方。如果它们依赖于父窗口(通常以特定活动的形式),则通常必须按照创建它们的相反顺序销毁它们。

很难跟踪您的代码,因此这是一个通用答案。

在您的活动中使用 onPause 和 onDestroy。

在您的所有活动中,管理您在该活动中创建的任何资源,并通过空检查将其关闭。就像您在服务级别中一样。如果您想覆盖父级 onDestroy,请将自定义代码放在 super.onDestroy 之前。

protected void onDestroy() {

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

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

    super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)