不同的方式启动一个应用,解决不重复启动相同的Activity的方式
Android 安装软件后执行“OPEN”引起的Intent血案(系统BUG)
编写:徐建祥(netpirate@gmail.com)
日期:2010/12/13
网址:http://www.anymobile.org
打开程序的入口有很多个:
shell 命令行运行;
Launcher待机界面执行;
状态通知栏运行;
桌面快捷方式运行;
软件中调用运行;
安装软件后执行“OPEN”运行!
前面几项,调用程序的代码如下(参考:com.android.Launcher/.Launcher.java):
?
view plaincopy to clipboardprint?- Intent?intent?=?new?Intent(this,?TestActivity.class);??
- intent.setAction(Intent.ACTION_MAIN);??
- intent.addCategory(Intent.CATEGORY_LAUNCHER);??
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);??
- intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);??
- this.startActivity(intent);??
?
而安装软件后,点击“Open”调用的代码如下(参考:com.android.packageinstaller/.InstallAppDone.java):
?
view plaincopy to clipboardprint?- Intent?intent?=?new?Intent(this,?TestActivity.class);??
- this.startActivity(intent);??
?
如果用户安装软件后立刻执行“Open”,运行程序后,按HOME键返回到后台,然后再通过别的几种方法运行程序,则会再起一个MAIN程序。这是因为Intent的处理机制是,先比较Activity,再比较Action、Flag、bnds。。。,前后两张方式的Action不一样,一个有LAUNCHER ACTION,一个没有,所以会认为是启动两个不同的INTENT。
目前只想到一个简单的处理方式:
程序入口MAIN程序:SplashActivity.java
程序原入口程序:LoginActivity.java
启动程序后,在状态通知栏上添加快捷通知,代码如下:
?
view plaincopy to clipboardprint?- package?org.anymobile.test;??
- import?android.app.Activity;??
- import?android.app.Notification;??
- import?android.app.NotificationManager;??
- import?android.app.PendingIntent;??
- import?android.content.ComponentName;??
- import?android.content.Context;??
- import?android.content.Intent;??
- import?android.os.Bundle;??
- public?class?SplashActivity?extends?Activity??
- {??
- ????@Override??
- ????protected?void?onCreate(Bundle?savedInstanceState)??
- ????{??
- ????????super.onCreate(savedInstanceState);??
- ??????????
- ????????this.showNotification(this.getBaseContext(),?-1,?"Test?is?Running!",?"Test?Start?Up!");??
- ??????????
- ????????Intent?intent?=?this.getIntent();??
- ????????if?(intent.hasCategory(Intent.CATEGORY_LAUNCHER))??
- ????????{??
- ????????????intent?=?new?Intent(this,?TestActivity.class);??
- ????????????this.startActivity(intent);??
- ????????}??
- ????????else??
- ????????{??
- ????????????intent?=?new?Intent();??
- ????????????ComponentName?componentName?=?new?ComponentName(this,?SplashActivity.class);??
- ????????????intent.setComponent(componentName);??
- //??????????intent?=?new?Intent(this,?SplashActivity.class);??
- ??????????????
- ????????????intent.setAction(Intent.ACTION_MAIN);??
- ????????????intent.addCategory(Intent.CATEGORY_LAUNCHER);??
- ????????????intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);??
- ????????????intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);??
- ??????????????
- ????????????this.startActivity(intent);??
- ????????}??
- ??????????
- ????????this.finish();??
- ????}??
- ????public?void?showNotification(Context?context,int?iResIcon,String?sNotifybar,String?sNofitymsg)??
- ????{??
- ????????//?look?up?the?notification?manager?service??
- ????????NotificationManager?nm?=?(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);??
- ????????//?The?details?of?our?fake?message??
- ????????CharSequence?from?=?"Test";??
- ????????CharSequence?message?=?sNofitymsg;??
- ??????????
- ????????Intent?intent?=?new?Intent();??
- ????????ComponentName?componentName?=?new?ComponentName(context,?TestActivity.class);??
- ????????intent.setComponent(componentName);??
- ??????????
- ????????intent.setAction(Intent.ACTION_MAIN);??
- ????????intent.addCategory(Intent.CATEGORY_LAUNCHER);??
- ????????intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);??
- ????????intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);??
- ??????????
- ????????PendingIntent?contentIntent?=?PendingIntent.getActivity(context,?0,?intent,?0);??
- ????????Notification?notification?=???
- ????????????new?Notification(iResIcon,sNotifybar,?System.currentTimeMillis());??
- ????????notification.flags?=?notification.flags?|?Notification.FLAG_ONGOING_EVENT;??
- ????????notification.defaults?=???
- ????????????/*Notification.DEFAULT_SOUND|*/Notification.DEFAULT_LIGHTS;??
- ????????notification.setLatestEventInfo(context,?from,?message,?contentIntent);??
- line-height: 18px; color: black; background-coandroid:launchMode="singleInstance"
试试。android:launchMode="singleInstance"
试试。
谢谢,管用 3 楼 anjxue 2011-12-01 使用singleInstance这个方法太草率了。
比如我们的根activity为A,给A设置singleInstance.
当只有一个A时没有问题,但当A上面有其它Activity时,就有问题的,比如A上面有B,C
这样当按home切回桌面,再次点击应用程序图标时,程序又返回到A而不是C!
显然通常情况下我们想要回到C的。
我也在寻找合适的解决办法。