天天看點

【移動開發】Android應用程式完全退出

前段期間,參加比賽做項目時遇到了一個問題:Android中應用程式彈出退出對話框退出應用程式時,老是出現上一個Activity,于是将在Activity跳轉時将其finish()掉,結果還是不行!尋其原因:原來項目中有好多Activity用來顯示界面,之間還摻紮着資料資訊的交流,我們知道Activity是以棧的方式存放,要想将程式退出,自然得将衆多Activity銷毀掉了!

後來在網上查閱了一下,找到了解決方法,在此總結一下前輩們知識,使其更加系統化!

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

首先要說明該方法運作在Android 1.5 API Level為3以上才可以,同時需要權限

1

2

<code>ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);</code>

<code> </code><code>am.restartPackage(getPackageName());</code>

系統會将,該包下的 ,所有程序,服務,全部殺掉,就可以殺幹淨了,要注意加上

<code>&lt;</code><code>uses-permission</code> <code>android:name=\"android.permission.RESTART_PACKAGES\"&gt;&lt;/</code><code>uses-permission</code><code>&gt;</code>

2.Dalvik VM的本地方法:

<code>android.os.Process.killProcess(android.os.Process.myPid())    </code><code>//擷取PID</code>

<code>System.exit(</code><code>0</code><code>);   </code><code>//正常java、c#的标準退出法,傳回值為0代表正常退出</code>

3.一種比較流行的Android經典完美退出方法:

使用單例模式建立一個Activity管理對象,該對象中有一個Activity容器(具體實作自己處理,使用LinkedList等)專門負責存儲新開啟的每一個Activity,并且容易了解、易于操作,非常不錯!

A.MyApplication類(儲存每一個Activity,并實作關閉所有Activity的操作)

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<code>public</code> <code>class</code> <code>MyApplication </code><code>extends</code> <code>Application {</code>

<code>    </code><code>//對于新增和删除操作add和remove,LinedList比較占優勢,因為ArrayList實作了基于動态數組的資料結構,要移動資料。LinkedList基于連結清單的資料結構,便于增加删除 </code>

<code>     </code><code>private</code> <code>List&lt;Activity&gt; activityList = </code><code>new</code> <code>LinkedList&lt;Activity&gt;();</code>

<code>     </code><code>private</code> <code>static</code> <code>MyApplication instance;</code>

<code>     </code><code>private</code> <code>MyApplication(){ }</code>

<code> </code><code>//單例模式中擷取唯一的MyApplication執行個體</code>

<code> </code><code>public</code> <code>static</code> <code>MyApplication getInstance() {</code>

<code>     </code><code>if</code><code>(</code><code>null</code> <code>== instance) {</code>

<code>        </code><code>instance = </code><code>new</code> <code>MyApplication();</code>

<code>     </code><code>}</code>

<code>     </code><code>return</code> <code>instance;</code>

<code> </code><code>}</code>

<code>//添加Activity到容器中</code>

<code>public</code> <code>void</code> <code>addActivity(Activity activity)  {</code>

<code>    </code><code>activityList.add(activity);</code>

<code>//周遊所有Activity并finish</code>

<code>public</code> <code>void</code> <code>exit(){</code>

<code> </code><code>for</code><code>(Activity activity:activityList) {</code>

<code>      </code><code>activity.finish();</code>

<code> </code><code>System.exit(</code><code>0</code><code>);</code>

<code>}</code>

B.在每一個Activity中的onCreate方法裡添加該Activity到MyApplication對象執行個體容器中

<code>MyApplication.getInstance().addActivity(</code><code>this</code><code>);</code>

C.在需要結束所有Activity的時候調用exit方法

<code>MyApplication.getInstance().exit();</code>

4.廣播方式:

A. MyAcitivty類說明:Acitivty的子類,基礎該類的子類必須實作onCreate 方法,在該類中注冊了一個BroadcastReceiver 用于接收退出消息,在接收到消息之後結束自身

25

<code>public</code> <code>abstract </code><code>class</code> <code>MyAcitivty </code><code>extends</code> <code>Activity {</code>

<code>         </code><code>/**負責各個具體 Activity 的顯示**/</code>

<code>         </code><code>public</code> <code>abstract </code><code>void</code> <code>onCreate();</code>

<code>        </code><code>@Override</code>

<code>         </code><code>public</code> <code>void</code> <code>onCreate(</code><code>final</code> <code>Bundle savedInstanceState) {</code>

<code>                 </code><code>// TODO Auto-generated method stub</code>

<code>                 </code><code>super</code><code>.onCreate(savedInstanceState);</code>

<code>                 </code><code>onCreate();</code>

<code>                 </code><code>RegListener();</code>

<code>         </code><code>}</code>

<code>        </code><code>/**注冊退出事件監聽**/</code>

<code>         </code><code>public</code> <code>void</code> <code>RegListener() {</code>

<code>            </code><code>ExitListenerReceiver exitre = </code><code>new</code> <code>ExitListenerReceiver();</code>

<code>            </code><code>IntentFilter intentfilter = </code><code>new</code> <code>IntentFilter();</code>

<code>            </code><code>intentfilter.addAction(</code><code>this</code><code>.getPackageName() + </code><code>"."</code>

<code>                                 </code><code>+ </code><code>"ExitListenerReceiver"</code><code>);</code>

<code>            </code><code>this</code><code>.registerReceiver(exitre, intentfilter);</code>

<code>         </code><code>class</code> <code>ExitListenerReceiver </code><code>extends</code> <code>BroadcastReceiver {</code>

<code>                </code><code>@Override</code>

<code>                 </code><code>public</code> <code>void</code> <code>onReceive(Context context, Intent i) {</code>

<code>                        </code><code>((Activity) context).finish();</code>

<code>                </code><code>}</code>

<code>        </code><code>}</code>

B.自己的Activity都繼承MyAcitivty,到需要退出程式的時候發送廣播

<code>Intent intent = </code><code>new</code> <code>Intent(context.getPackageName()+</code><code>".ExitListenerReceiver"</code><code>);</code>

<code>context.sendBroadcast(intent);</code>

即可。

5.一個技巧方式:

A.首先設定一個公用的class: Setting.java,定義一個靜态類成員

<code>public</code> <code>boolean </code><code>static</code> <code>isCloseAll=</code><code>false</code><code>;</code>

B.然後,在每一個Activity的onResume()加入這一個:

<code>@Override</code>

<code> </code><code>onResume() {</code>

<code>     </code><code>super</code><code>.onResume();</code>

<code>     </code><code>if</code><code>(Setting.isCloseAll) finish();</code>

C.當最後一個Activity需要結束整個程式便執行:

<code>Setting.isCloseAll=</code><code>true</code><code>;</code>

<code>finish();</code>

6.捕獲空指針異常

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

<code>package</code> <code>com.example.android_uncatchexception;</code>

<code>import</code> <code>android.app.Application;</code>

<code>public</code> <code>class</code> <code>MyCrashApplication </code><code>extends</code> <code>Application {</code>

<code>    </code><code>@Override</code>

<code>    </code><code>public</code> <code>void</code> <code>onCreate() {</code>

<code>        </code><code>super</code><code>.onCreate();</code>

<code>        </code><code>//程式一啟動,就将未捕獲異常初始化</code>

<code>        </code><code>CrashHandler.getInstance().init(getApplicationContext());</code>

<code>    </code><code>}</code>

注:記得注冊Application

B.自定義異常捕獲類:

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

<code>import</code> <code>java.lang.Thread.UncaughtExceptionHandler;</code>

<code>import</code> <code>android.content.Context;</code>

<code>import</code> <code>android.util.Log;</code>

<code>/**</code>

<code> </code><code>* 自定義異常捕獲類</code>

<code> </code><code>*</code>

<code> </code><code>* @author ZHF</code>

<code> </code><code>*/</code>

<code>public</code> <code>class</code> <code>CrashHandler </code><code>implements</code> <code>UncaughtExceptionHandler {</code>

<code>    </code><code>public</code> <code>static</code> <code>final</code> <code>String</code> <code>TAG = </code><code>"CrashHandler"</code><code>;</code>

<code>    </code><code>// 程式的Context對象</code>

<code>    </code><code>private</code> <code>Context mContext;</code>

<code>    </code><code>/** 單例模式 **/</code>

<code>    </code><code>private</code> <code>CrashHandler() {</code>

<code>    </code><code>/** 懶漢式 **/</code>

<code>    </code><code>private</code> <code>static</code> <code>class</code> <code>CrashHolder {</code>

<code>        </code><code>static</code> <code>final</code> <code>CrashHandler crashHandler = </code><code>new</code> <code>CrashHandler();</code>

<code>    </code><code>public</code> <code>static</code> <code>CrashHandler getInstance() {</code>

<code>        </code><code>return</code> <code>CrashHolder.crashHandler;</code>

<code>    </code><code>public</code> <code>void</code> <code>init(Context context) {</code>

<code>        </code><code>mContext = context;</code>

<code>        </code><code>// 設定該CrashHandler為程式的預設處理器</code>

<code>        </code><code>Thread.setDefaultUncaughtExceptionHandler(</code><code>this</code><code>);</code>

<code>    </code><code>public</code> <code>void</code> <code>uncaughtException(Thread thread, Throwable ex) {</code>

<code>        </code><code>Log.d(TAG,</code>

<code>                </code><code>"uncaughtException---&gt;thread"</code> <code>+ thread + </code><code>" name: "</code>

<code>                        </code><code>+ thread.getName() + </code><code>" id: "</code> <code>+ thread.getId() + </code><code>"exception---&gt;"</code> <code>+ ex);</code>

<code>                                                            </code> 

<code>        </code><code>String</code> <code>threadName = thread.getName();</code>

<code>        </code><code>if</code><code>(</code><code>"main"</code><code>.equals(threadName)) {</code>

<code>            </code><code>Log.d(TAG, </code><code>"在主線程的崩潰!"</code><code>);</code>

<code>        </code><code>}</code><code>else</code> <code>{</code>

<code>            </code><code>//這裡我們根據thread name來進行差別對待:可以将異常資訊寫入檔案供以後分析</code>

<code>            </code><code>Log.d(TAG, </code><code>"在子線程中崩潰!"</code><code>);</code>

<code>        </code><code>android.os.Process.killProcess(android.os.Process.myPid()); </code><code>//殺死該程序</code>

<code>        </code><code>System.exit(</code><code>0</code><code>); </code><code>//退出</code>

C.在要退出的地方制造空指針異常即可實作閃退,并且不會彈出ANR對話框

<code>import</code> <code>android.os.Bundle;</code>

<code>import</code> <code>android.app.Activity;</code>

<code>import</code> <code>android.view.View;</code>

<code>import</code> <code>android.view.View.OnClickListener;</code>

<code>import</code> <code>android.widget.Button;</code>

<code>public</code> <code>class</code> <code>MainActivity </code><code>extends</code> <code>Activity {</code>

<code>              </code> 

<code>    </code><code>Button mBtn;</code>

<code>    </code><code>String</code> <code>str; </code><code>//不要初始化,為了下面制造空指針異常</code>

<code>    </code><code>protected</code> <code>void</code> <code>onCreate(Bundle savedInstanceState) {</code>

<code>        </code><code>super</code><code>.onCreate(savedInstanceState);</code>

<code>        </code><code>setContentView(R.layout.activity_main);</code>

<code>                  </code> 

<code>        </code><code>mBtn = (Button) </code><code>this</code><code>.findViewById(R.id.button1);</code>

<code>        </code><code>mBtn.setOnClickListener(</code><code>new</code> <code>OnClickListener() {</code>

<code>            </code><code>@Override</code>

<code>            </code><code>public</code> <code>void</code> <code>onClick(View v) {</code>

<code>                </code><code>//NullPointerException</code>

<code>                </code><code>System.out.println(str);</code>

<code>            </code><code>}</code>

<code>        </code><code>});</code>

7.網上還有一些其他方式:

A.restartPackage、

B. killBackgroundProcesses

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

<b>     本文轉自zhf651555765 51CTO部落格,原文連結:http://blog.51cto.com/smallwoniu/1248643</b><b>,如需轉載請自行聯系原作者</b>