溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

【移動(dòng)開發(fā)】Android應(yīng)用程序完全退出

發(fā)布時(shí)間:2020-07-09 07:47:52 來源:網(wǎng)絡(luò) 閱讀:21848 作者:zhf651555765 欄目:開發(fā)技術(shù)

前段期間,參加比賽做項(xiàng)目時(shí)遇到了一個(gè)問題:Android中應(yīng)用程序彈出退出對(duì)話框退出應(yīng)用程序時(shí),老是出現(xiàn)上一個(gè)Activity,于是將在Activity跳轉(zhuǎn)時(shí)將其finish()掉,結(jié)果還是不行!尋其原因:原來項(xiàng)目中有好多Activity用來顯示界面,之間還摻扎著數(shù)據(jù)信息的交流,我們知道Activity是以棧的方式存放,要想將程序退出,自然得將眾多Activity銷毀掉了!

后來在網(wǎng)上查閱了一下,找到了解決方法,在此總結(jié)一下前輩們知識(shí),使其更加系統(tǒng)化!


1.任務(wù)管理器方法(ActivityManager):

首先要說明該方法運(yùn)行在Android 1.5 API Level為3以上才可以,同時(shí)需要權(quán)限

ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);
 am.restartPackage(getPackageName());

系統(tǒng)會(huì)將,該包下的 ,所有進(jìn)程,服務(wù),全部殺掉,就可以殺干凈了,要注意加上

<uses-permission android:name=\"android.permission.RESTART_PACKAGES\"></uses-permission>


2.Dalvik VM的本地方法:

android.os.Process.killProcess(android.os.Process.myPid())    //獲取PID
System.exit(0);   //常規(guī)java、c#的標(biāo)準(zhǔn)退出法,返回值為0代表正常退出


3.一種比較流行的Android經(jīng)典完美退出方法:

使用單例模式創(chuàng)建一個(gè)Activity管理對(duì)象,該對(duì)象中有一個(gè)Activity容器(具體實(shí)現(xiàn)自己處理,使用LinkedList等)專門負(fù)責(zé)存儲(chǔ)新開啟的每一個(gè)Activity,并且容易理解、易于操作,非常不錯(cuò)!


A.MyApplication類(儲(chǔ)存每一個(gè)Activity,并實(shí)現(xiàn)關(guān)閉所有Activity的操作)


public class MyApplication extends Application {
    //對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢(shì),因?yàn)锳rrayList實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),要移動(dòng)數(shù)據(jù)。LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu),便于增加刪除  
     private List<Activity> activityList = new LinkedList<Activity>();
     private static MyApplication instance;
     private MyApplication(){ }
 //單例模式中獲取唯一的MyApplication實(shí)例
 public static MyApplication getInstance() {
     if(null == instance) {
        instance = new MyApplication();
     }
     return instance;
 }
//添加Activity到容器中
public void addActivity(Activity activity)  {
    activityList.add(activity);
 }
//遍歷所有Activity并finish
public void exit(){
 for(Activity activity:activityList) {
      activity.finish();
 }
 System.exit(0);
 }
}

B.在每一個(gè)Activity中的onCreate方法里添加該ActivityMyApplication對(duì)象實(shí)例容器中

MyApplication.getInstance().addActivity(this);

C.在需要結(jié)束所有Activity的時(shí)候調(diào)用exit方法

MyApplication.getInstance().exit();

4.廣播方式:

A. MyAcitivty類說明:Acitivty的子類,基礎(chǔ)該類的子類必須實(shí)現(xiàn)onCreate 方法,在該類中注冊(cè)了一個(gè)BroadcastReceiver 用于接收退出消息,在接收到消息之后結(jié)束自身

public abstract class MyAcitivty extends Activity {
         /**負(fù)責(zé)各個(gè)具體 Activity 的顯示**/
         public abstract void onCreate();
        @Override
         public void onCreate(final Bundle savedInstanceState) {
                 // TODO Auto-generated method stub
                 super.onCreate(savedInstanceState);
                 onCreate();
                 RegListener();
         }
        /**注冊(cè)退出事件監(jiān)聽**/
         public void RegListener() {
            ExitListenerReceiver exitre = new ExitListenerReceiver();
            IntentFilter intentfilter = new IntentFilter();
            intentfilter.addAction(this.getPackageName() + "."
                                 + "ExitListenerReceiver");
            this.registerReceiver(exitre, intentfilter);
         }
         class ExitListenerReceiver extends BroadcastReceiver {
                @Override
                 public void onReceive(Context context, Intent i) {
                        ((Activity) context).finish();
                }
        }
}

B.自己的Activity都繼承MyAcitivty,到需要退出程序的時(shí)候發(fā)送廣播

Intent intent = new Intent(context.getPackageName()+".ExitListenerReceiver");
context.sendBroadcast(intent);

即可。


5.一個(gè)技巧方式:

A.首先設(shè)定一個(gè)公用的class: Setting.java,定義一個(gè)靜態(tài)類成員

public boolean static isCloseAll=false;

B.然后,在每一個(gè)ActivityonResume()加入這一個(gè):

@Override
 onResume() {
     super.onResume();
     if(Setting.isCloseAll) finish();
}

C.當(dāng)最后一個(gè)Activity需要結(jié)束整個(gè)程序便執(zhí)行:

Setting.isCloseAll=true;
finish();


6.捕獲空指針異常

A.通過異常并在Application的子類中重新注冊(cè)Thread的 Thread.UncaughtExceptionHandler接口:

package com.example.android_uncatchexception;
import android.app.Application;
public class MyCrashApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //程序一啟動(dòng),就將未捕獲異常初始化
        CrashHandler.getInstance().init(getApplicationContext());
    }
}

注:記得注冊(cè)Application


B.自定義異常捕獲類:

package com.example.android_uncatchexception;
import java.lang.Thread.UncaughtExceptionHandler;
import android.content.Context;
import android.util.Log;
/**
 * 自定義異常捕獲類
 *
 * @author ZHF
 */
public class CrashHandler implements UncaughtExceptionHandler {
    public static final String TAG = "CrashHandler";
    // 程序的Context對(duì)象
    private Context mContext;
    /** 單例模式 **/
    private CrashHandler() {
    }
    /** 懶漢式 **/
    private static class CrashHolder {
        static final CrashHandler crashHandler = new CrashHandler();
    }
    public static CrashHandler getInstance() {
        return CrashHolder.crashHandler;
    }
    public void init(Context context) {
        mContext = context;
        // 設(shè)置該CrashHandler為程序的默認(rèn)處理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        Log.d(TAG,
                "uncaughtException--->thread" + thread + " name: "
                        + thread.getName() + " id: " + thread.getId() + "exception--->" + ex);
                                                            
        String threadName = thread.getName();
        if("main".equals(threadName)) {
            Log.d(TAG, "在主線程的崩潰!");
        }else {
            //這里我們根據(jù)thread name來進(jìn)行區(qū)別對(duì)待:可以將異常信息寫入文件供以后分析
            Log.d(TAG, "在子線程中崩潰!");
        }
                                                            
        android.os.Process.killProcess(android.os.Process.myPid()); //殺死該進(jìn)程
        System.exit(0); //退出
    }
}

C.在要退出的地方制造空指針異常即可實(shí)現(xiàn)閃退,并且不會(huì)彈出ANR對(duì)話框

package com.example.android_uncatchexception;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
              
    Button mBtn;
    String str; //不要初始化,為了下面制造空指針異常
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                  
        mBtn = (Button) this.findViewById(R.id.button1);
        mBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //NullPointerException
                System.out.println(str);
            }
        });
    }
}




7.網(wǎng)上還有一些其他方式:

A.restartPackage、

B. killBackgroundProcesses

不常用,大家可以自行參考哦~






向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI