服务自动调用摧毁活动 [英] Service Automatic Called on Destroying Activity

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

问题描述

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

活动:


  

LoginActivity => OrderListActivity => AddOrderActivity => ConfirmOrderActivity


服务:


  1. ReceivingOrderService - 接收新数据从服务器

  2. SendingOrderService - 发送新数据到服务器

以上两种服务从另一个单独的服务上的一些间隔持续时间呼叫

<醇开始=3>
  • CheckAutoSyncReceivingOrder - 要调用ReceivingOrderService(间隔15分钟)

  • CheckAutoSyncSendingOrder - 要调用SendingOrderService(间隔3Mins)

  • CheckAutoSyncReceivingOrder:

     公共类CheckAutoSyncReceivingOrder延伸服务{    定时器定时器;    @覆盖
        公众的IBinder onBind(意向为arg0){
            // TODO自动生成方法存根
            返回null;
        }    @覆盖
        公共无效调用onStart(意向意图,诠释startId){
            // TODO自动生成方法存根        如果(定时器!= NULL){
                timer.cancel();
                Log.i(TAG,接收OLD TIMER已取消&GT;&GT;&GT;);
            }        定时器=新定时器();        timer.schedule(新的TimerTask(){
                @覆盖
                公共无效的run(){
                    如果(InternetConnection.checkConnection(getApplicationContext())){
                        如果(getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                            startService(新意图(CheckAutoSyncReceivingOrder.this,ReceivingOrderService.class));
                    }其他{
                        Log.d(TAG,连接不可用);
                    }
                }
            },0,60000); // 1000 * 60 * 15 = 9,00,000 =15分钟
        }    @覆盖
        公共无效的onDestroy(){
            // TODO自动生成方法存根
            super.onDestroy();        如果(定时器!= NULL)
                timer.cancel();        Log.d(TAG,停止接收...);
        }
    }

    CheckAutoSyncSendingOrder:

     公共类CheckAutoSyncSendingOrder延伸服务{    定时器定时器;    @覆盖
        公众的IBinder onBind(意向为arg0){
            // TODO自动生成方法存根
            返回null;
        }    @覆盖
        公共无效调用onStart(意向意图,诠释startId){
            // TODO自动生成方法存根        如果(定时器!= NULL){
                timer.cancel();
                Log.i(TAG,老家伙已取消&GT;&GT;&GT;);
            }        定时器=新定时器();        timer.schedule(新的TimerTask(){
                @覆盖
                公共无效的run(){
                    Log.i(TAG,&GT;&GT;&GT;&GT;&GT;&GT;&GT;&GT;将自动同步服务&GT;&GT;&GT;&GT;&GT;&GT;&GT;&GT;);
                    如果(InternetConnection.checkConnection(getApplicationContext())){
                        如果(getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                            startService(新意图(CheckAutoSyncSendingOrder.this,SendingOrderService.class));
                    }其他{
                        Log.d(TAG,连接不可用);
                    }
                }
            },0,120000); // 1000 * 120 * 15 = 1800000 =15分钟
        }    @覆盖
        公共无效的onDestroy(){
            // TODO自动生成方法存根
            super.onDestroy();        如果(定时器!= NULL)
                timer.cancel();        Log.d(TAG,停止发送...);
        }
    }

    ConfirmOrderActivity#最后的任务,我呼吁插入数据:

     新的AsyncTask&LT;太虚,太虚,整数GT;(){    ProgressDialog progressDialog;    @覆盖
        在preExecute保护无效(){
            // TODO自动生成方法存根
            super.on preExecute();        progressDialog =新ProgressDialog(
                    ConfirmOrderProductActivity.this);
            progressDialog.setMessage(插入
                    +(?isInquiry探究:订单)+...);
            progressDialog.setCancelable(假);
            progressDialog
                    .setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.show();
        }    @覆盖
        保护整数doInBackground(虚空...... PARAMS){
            // TODO自动生成方法存根
            INT ACCOUNT_ID = context.getShared preferences(preF_DATA,
                    MODE_APPEND).getInt(DATA_ACCOUNT_ID,0);        / **
             *检查是否isInquiry或不...
             * /
            产品类型= isWeight? 1:0;
            如果(isInquiry){
                / *
                 *中插入询价表中的数据
                 * /
                返回m_inquiry_id;
            }其他{
                / *
                 * INSERTING为了表数据
                 * /
                返回m_order_id;
            }
        }    @覆盖
        保护无效onPostExecute(整数m_order_id){
            // TODO自动生成方法存根
            super.onPostExecute(m_order_id);        progressDialog.dismiss();        如果(dbHelper.db.isOpen())
                dbHelper.close();        字符串title =重试;
            字符串消息=有一些问题,回去重试;        AlertDialog.Builder警报=新AlertDialog.Builder(
                    ConfirmOrderProductActivity.this);        如果(m_order_id!= -1){
                标题= isInquiry? 新咨询:新秩序;
                消息= isInquiry? 你的查询发送成功。 :您的订单已成功保存。
                alert.setIcon(R.drawable.success).setCancelable(假);
            }其他{
                alert.setIcon(R.drawable.fail).setCancelable(假);
            }        alert.setTitle(职称).setMessage(消息)
                    .setPositiveButton(OK,新OnClickListener(){                    @覆盖
                        公共无效的onClick(DialogInterface对话框,
                                其中INT){
                            // TODO自动生成方法存根
                            dialog.dismiss();
                            startActivity(新意图(
                                    ConfirmOrderProductActivity.this,
                                    FragmentChangeActivity.class)
                                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));                        / *开放左至右动画* /
                            overridePendingTransition(R.anim.right_out,
                                    R.anim.right_in);
                        }
                    });        AlertDialog alertDialog = alert.create();
            alertDialog.show();    }
    }。执行();

    一切正常按在数据库中插入记录的流量。

    添加询问后:

    销毁活动,并获得以下的logcat:

    主要问题:

    当我把为了成功地从 ConfirmOrderActivity ,它显示的是 AlertDialog 成功留言即的撤销 。当我从这个活动停止的应用程序,它调用这两个 CheckAutoSyncReceivingOrder CheckAutoSyncSendingOrder 自动

    编辑:


      

    我打电话从 LoginActivity 这两个服务而已,以后它
      给定的间隔,但存在问题发生之后会自动调用
      当我摧毁的 ConfirmOrderActivity 时,将显示对话框。


    我不知道为什么会发生那为什么它会自动运行时,我直接停止活动。

    我曾尝试 onStartCommand() START_NON_STICKY 服务但不工作。 (如 START_STICKY 是默认设置。)

      @覆盖
    公众诠释onStartCommand(意向意图,诠释标志诠释startId){
        返回START_NOT_STICKY;
    }

    请问有什么解决办法吗?


    解决方案

    您需要或者运行您的在前台服务所以当活动被销毁,将服务或使用绑定的服务和管理活动生命周期的结合,所以当活动被销毁未持续重新启动。

    从这个机器人文档教程绑定服务

    您需要为每项服务做到这一点。

     公共类CheckAutoSyncReceivingOrder延伸服务{
        //粘结剂提供给客户端
        私人最终的IBinder mBinder =新LocalBinder();    公共类LocalBinder扩展粘结剂{
            CheckAutoSyncReceivingOrder的getService(){
            返回CheckAutoSyncReceivingOrder.this;
        }
    }    @覆盖
        公众的IBinder onBind(意向意图){
            返回mBinder;
        }

    从您的活动创建和调用服务,当它被摧毁你希望你的服务被破坏。

     公共类BindingActivity延伸活动{
        CheckAutoSyncReceivingOr MSERVICE;
        布尔mBound = FALSE;
        @覆盖
        保护无效调用onStart(){
            super.onStart();
            //绑定到CheckAutoSyncReceivingOr
            意向意图=新意图(这一点,CheckAutoSyncReceivingOr.class);
            bindService(意向,mConnection,Context.BIND_AUTO_CREATE);
        }    @覆盖
        保护无效的onStop(){
            super.onStop();
            //取消绑定从服务
            如果(mBound){
                unbindService(mConnection);
                mBound = FALSE;
            }
        }    / **定义服务绑定,传递给bindService()回调* /
        私人ServiceConnection mConnection =新ServiceConnection(){        @覆盖
            公共无效onServiceConnected(组件名类名,
                的IBinder服务){
                //我们势必CheckAutoSyncReceivingOr,施放的IBinder并获得CheckAutoSyncReceivingOr实例
                LocalBinder粘结剂=(LocalBinder)服务;
                MSERVICE = binder.getService();
                mBound = TRUE;
            }        @覆盖
            公共无效onServiceDisconnected(组件名称为arg0){
                mBound = FALSE;
            }
        };
    }

    和管理服务生命周期。与你的计时器重新启动同样的服务,不创建一个新的服务。

     公共类ExampleService延伸服务{
        INT mStartMode; //指示如何做人,如果该服务被杀害
        的IBinder mBinder; //接口,用于客户端绑定
        布尔mAllowRebind; //表示onRebind是否应使用    @覆盖
        公共无效的onCreate(){
            //正在创建的服务
        }
        @覆盖
        公众诠释onStartCommand(意向意图,诠释标志诠释startId){
            //该服务正在启动,由于对startService()的调用
            返回mStartMode;
        }
        @覆盖
        公众的IBinder onBind(意向意图){
            //一个客户端)的结合与bindService服务(
            返回mBinder;
        }
        @覆盖
        公共布尔onUnbind(意向意图){
            //所有客户端绑定与unbindService()
            返回mAllowRebind;
        }
        @覆盖
        公共无效onRebind(意向意图){
            //客户端绑定到与bindService服务()
            //后onUnbind()已经被调用
        }
        @覆盖
        公共无效的onDestroy(){
            //该服务不再使用,被销毁
        }
    }

    请注意 START_NOT_STICKY 只会prevent重新启动,如果设备内存不足的服务。

    要留意你,你已经开始服务,刚开始一次,使服务能够保持它自己的生命周期,直到你与你的活动摧毁它。

    这是在回答你原来未经编辑的问题,当应用程序被神秘崩溃:

    您需要的对话框被附加到上下文窗口之前破坏对话。这将引起问题。因此,这是程序流和关闭的顺序,并清理资源是非常重要的。它们经常具有以相反的顺序,他们如果它们是依赖于父窗口(通常是在一个特定的活动的形式)被创建被销毁。

    这是很难跟踪你的code,所以这是一个通用的答案。

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

    在所有的活动,管理您有活动中,并用空检查创建的任何资源,关闭它们。就像你在你的服务类。如果你想重写父的onDestroy,将您的自定义code super.onDestroy之前。

     保护无效的onDestroy(){    如果(定时器!= NULL)
            timer.cancel();    Log.d(TAG,停止发送...);    super.onDestroy();
    }

    I am stuck with the problem of Activity + Service in that I have following number of Activities and Services.

    Activities:

    LoginActivity => OrderListActivity => AddOrderActivity => ConfirmOrderActivity

    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 am calling both Service from LoginActivity only, after that it will called automatically after given intervals But Problem occurs when I destroy ConfirmOrderActivity when dialog is shown.

    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();
    }
    

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

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆