Android 2.2完全退出程序, 运用广播机制

Android 2.2完全退出程序, 使用广播机制
这个问题一直困扰着我,试了n种方式,都不行,在网上搜了一圈,没有能用的:

1.ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
manager.killBackgroundProcesses(package);
不行

2.android.os.Process.killProcess(android.os.Process.myPid());
也不行

3.manager.restartPackage(package);
还是不行


4.
Intent MyIntent = new Intent(Intent.ACTION_MAIN);
MyIntent.addCategory(Intent.CATEGORY_HOME);
startActivity(MyIntent);
finish();
这个只是退回到桌面,如果打开多个Activity关闭重新打开也会有问题,还是还是不行

看到有说广播机制,发现是个好东东,能彻底解决这个问题,废话不说看代码:
public abstract class EnterActivity extends BaseActivity {
...
	// 写一个广播的内部类,当收到动作时,结束activity
	private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			unregisterReceiver(this); // 这句话必须要写要不会报错,不写虽然能关闭,会报一堆错
			((Activity) context).finish();
		}
	};

	@Override
	public void onResume() {
		super.onResume();

		// 在当前的activity中注册广播
		IntentFilter filter = new IntentFilter();
		filter.addAction(Attribute.PAGENAME);
		registerReceiver(this.broadcastReceiver, filter); // 注册
	}

	/**
	 * 关闭
	 */
	public void close() {
		Intent intent = new Intent();
		intent.setAction(Attribute.PAGENAME); // 说明动作
		sendBroadcast(intent);// 该函数用于发送广播
		finish();
	}
...
}


别人写的缺了个地方(unregisterReceiver)这个必须要加,找了个最简单的方法
1 楼 thihy 2011-08-10  
完全退出程序是啥意思?
2 楼 iaiai 2011-08-11  
在android 2.2上你打开多个activity的时候,这时候你想退出的话你是关不掉所有打开的activity的,必须要通过我上面的这种方式关闭
3 楼 eimsteim 2011-08-25  
请问 Attribute.PAGENAME 这是从哪里来的?

另外怎样触发那个广播呢?
4 楼 eimsteim 2011-08-25  
按照你推荐的方法,我在Activity02中设置了一个退出按钮,onclick事件中调用close()方法,使用finish()时会报receiver not registered,而如果使用System.exit(0)替代,则只能退出当前的Activity02,而不能退出整个应用,不知道LZ有没有自己试过这个方法?是否可行呢?
5 楼 eimsteim 2011-08-25  
附上我的Activity02的代码:
	//写一个广播的内部类,当收到动作时,结束activity
	private BroadcastReceiver br = new BroadcastReceiver() {
		
		@Override
		public void onReceive(Context context, Intent intent) {
			close();
			unregisterReceiver(this);
		}
	};
	@Override
	protected void onResume() {
		super.onResume();
		
		//在当前Activity中注册广播
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_MAIN);
		registerReceiver(this.br, filter);	//注册
		
		System.out.println("Activity02---------------------------->onResume");
	}
	/**
	 * 关闭
	 */
	public void close(){
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_MAIN);
		sendBroadcast(intent);	//该函数用于发送广播
//		finish();
		System.exit(0);
	}
6 楼 iaiai 2011-08-25  
eimsteim 写道
按照你推荐的方法,我在Activity02中设置了一个退出按钮,onclick事件中调用close()方法,使用finish()时会报receiver not registered,而如果使用System.exit(0)替代,则只能退出当前的Activity02,而不能退出整个应用,不知道LZ有没有自己试过这个方法?是否可行呢?


你说的方法我当然试过,不用说肯定试过了,网上说的很多方法都试过,所有说的在2.2系统下都不行,System.exit(0)我不太建议用这种关闭方式,因为这种方式会有个问题,就是如果你启动服务,或是开了一些其它线程,你用这种方式会把那些线程都关闭掉,但是我只是想关闭的是所有activity,在后台运行的线程我并不想关闭,所以只能用finish这个方法去把activity关闭掉。

你报的那个错你看一下是不是调用过
registerReceiver(this.br, filter);  //注册
这句注册的话,还有就是你是不是调用了两编close()这个方法,总之我给你的是一种广播的思路,你只要会用广播这种试的话你就应该知道怎么样去关闭所有activity了
7 楼 eimsteim 2011-08-26  
你好,根据你的建议,我重新温习了一下广播的相关知识,重新看你的代码,发现有些地方不太能够理解了:
sendBroadcast(intent);// 该函数用于发送广播
这行为什么要放在close()里呢?

如果我的“退出”按钮OnClickListener中调用close()进行关闭操作的话,不就给BroadcastReceiver 发送了一个广播吗?然后在广播的onReceive()回调中,又会调用close(),这不就形成了一个闭环递归吗?
8 楼 eimsteim 2011-08-26  
而且,为何要在广播中去杀掉进程呢?当前进程在未处于onStop状态时,及时调用广播来处理,也不能杀不掉吧?
9 楼 iaiai 2011-08-26  
eimsteim 写道
你好,根据你的建议,我重新温习了一下广播的相关知识,重新看你的代码,发现有些地方不太能够理解了:
sendBroadcast(intent);// 该函数用于发送广播
这行为什么要放在close()里呢?

如果我的“退出”按钮OnClickListener中调用close()进行关闭操作的话,不就给BroadcastReceiver 发送了一个广播吗?然后在广播的onReceive()回调中,又会调用close(),这不就形成了一个闭环递归吗?


呵呵呵,你真是纠结,我写的确实有问题,现在改过来了,你自己能看懂就可以了,其实你想的并没有错,确实如果在广播体内放close()是套在循环里了.
10 楼 iaiai 2011-08-26  
eimsteim 写道
而且,为何要在广播中去杀掉进程呢?当前进程在未处于onStop状态时,及时调用广播来处理,也不能杀不掉吧?


如果不用广播我想知道你怎么样关闭打开的所有Activity,我说的关闭不了的情况是在android 2.2系统中发现关不掉的,如果像网上其它人说的用System.exit是关不掉的,并且调用此方法会出现其它一系列的问题,比如如果后台开着线程你调用System.exit会直接把你线程杀掉,这问题我写的代码的时候遇到了,找了好久才找到是System.exit给杀掉了,所以如果想关闭所有打开的activity必须得知道你打开所有的activity,用广播的方法其实感觉比较简单一些,只要发条通知关闭操作就可以了。当然你也可以用一个变量把所有打开的activity存储下来,我没用这种方式感觉太......
在android里没有彻底关闭软件的方法,网上现在讨论有两类,一类是熟悉windows操作习惯点击关闭就彻底关闭系统,但另一类人主张的不用彻底关闭,因为下次再打开的时候速度会快,并且如果内存不够的时候android会自动管理内存,关闭一些,总之不提供关闭方法确实是很麻烦的一件事情
11 楼 飞扬云 2011-09-26  
用了此方法,感觉还是可以的。不过我把finish方法换成了杀死进程的方法:
android.os.Process.killProcess(android.os.Process.myPid());
12 楼 zht19880706 2011-10-30  
我的那个完全退出不了,退出之后,就自动跳转成出异常的那个界面
13 楼 meteor0626 2012-01-14  
确实可以完全退出,但是在点击返回按键的时候会出错。

01-14 01:18:14.612: ERROR/ActivityThread(283): Activity com.cnki.homeActivity has leaked IntentReceiver com.cnki.homeActivity$3@43e74868 that was originally registered here. Are you missing a call to unregisterReceiver()?
01-14 01:18:14.612: ERROR/ActivityThread(283): android.app.IntentReceiverLeaked: Activity com.cnki.homeActivity has leaked IntentReceiver com.cnki.homeActivity$3@43e74868 that was originally registered here. Are you missing a call to unregisterReceiver()?
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:939)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:734)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:791)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:778)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:772)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at com.cnki.homeActivity.onResume(homeActivity.java:596)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1149)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.Activity.performResume(Activity.java:3823)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3118)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3143)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2684)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.os.Looper.loop(Looper.java:123)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at android.app.ActivityThread.main(ActivityThread.java:4627)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at java.lang.reflect.Method.invokeNative(Native Method)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at java.lang.reflect.Method.invoke(Method.java:521)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-14 01:18:14.612: ERROR/ActivityThread(283):     at dalvik.system.NativeStart.main(Native Method)