task是在程序运行时,只针对activity的概念。说白了,task是一组相互关联的activity的集合,它是存在于framework层的一个概念,控制界面的跳转和返回。这个task存在于一个称为back stack的数据结构中,也就是说,framework是以栈的形式管理用户开启的activity。这个栈的基本行为是,当用户在多个activity之间跳转时,执行压栈操作,当用户按返回键时,执行出栈操作。举例来说,如果应用程序中存在A,B,C三个activity,当用户在Launcher或Home Screen点击应用程序图标时,启动主Activity A,接着A开启B,B开启C,这时栈中有三个Activity,并且这三个Activity默认在同一个任务(task)中,当用户按返回时,弹出C,栈中只剩A和B,再按返回键,弹出B,栈中只剩A,再继续按返回键,弹出A,任务被移除。如下图所示:
singlerInstance其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。
SingleInstance模式启动的Activity在系统中具有全局唯一性。就是单列的效果
1.MediamainActivity 被重新创建了oncreate方法,前面的所有的activity都没有销毁
standard----每次点击图标或home键的时候重新创建MediamainActivity , MediamainActivity 有多个OnCreate方法执行
2.singleTask:
先进入了MediamainActivity ,再进入了Videoplay的话,点击图标
MediamainActivity 在顶,显示顶端的!
singleTask和其他所有的区别在于:Mediamain只有一个,销毁前面的所有的activity
有一个Mediamain只,执行onNewIntent()和singleInstance一样!
就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈
其他的videoPlay,audioplay,imagePlay都销毁了
3.先进入了MediamainActivity ,再进入了Videoplay的话,点击图标
MediamainActivity 在顶,显示顶端的!和Stander不一样
singleInstance和其他所有的区别在于:Mediamain只有一个,前面的所有的activity都没有销毁
singleInstance(多个应用程序共享一个应用)===比如说:在语音中调用多媒体程序!!
singleTop ,这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。
如果栈顶不存在该Activity的实例,则情况与standard模式相同
singleTop模式分3种情况
是不是同一个实例:hashcode值
案例分析:
standard,创建一个新的Activity。
singleTop,栈顶不是该类型的Activity,创建一个新的Activity。否则,onNewIntent。
singleTask,回退栈中没有该类型的Activity,创建Activity,否则,onNewIntent+ClearTop。
注意: 1.设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的Task存在; 如果存在这样的Task,它就会在这个Task中启动,否则就会在新的任务栈中启动。
因此, 如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。
2.如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例, 如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity 实例会位于任务的Stack顶端中。
3.在一个任务栈中只有一个”singleTask”启动模式的Activity存在。他的上面可以有其他的Activity。这点与singleInstance是有区别的。
singleInstance,回退栈中,只有这一个Activity,没有其他Activity。
singleTop适合接收通知启动的内容显示页面。 例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。 singleTask适合作为程序入口点。 例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance应用场景:闹铃的响铃界面。 你以前设置了一个闹铃:上午6点。在上午5点58分,你启动了闹铃设置界面,并按 Home 键回桌面;在上午5点59分时,你在微信和朋友聊天; 在6点时,闹铃响了,并且弹出了一个对话框形式的 Activity(名为 AlarmAlertActivity) 提示你到6点了(这个 Activity 就是以 SingleInstance 加载模式打开的),你按返回键,回到的是微信的聊天界面,这是因为 AlarmAlertActivity 所在的 Task 的栈只有他一个元素, 因此退出之后这个 Task 的栈空了。如果是以 SingleTask 打开 AlarmAlertActivity,那么当闹铃响了的时候,按返回键应该进入闹铃设置界面。
实例:
Intent flag的重要标志之一: FLAG_ACTIVITY_NEW_TASK
在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,不然会报异常。
private void NotifBar(File myTempFile) { if (notifiManager == null) { notifiManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE); } notifiManager.cancel(UpdateNotifId); if (notif != null) { notif = null; } NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); RemoteViews contentView = new RemoteViews(this.getPackageName(), R.layout.base_download_act); contentView.setTextViewText(R.id.down_tx, this.getString(R.string.downloadDone)); builder.setContentTitle(this.getString(R.string.downloadDone)); builder.setContentText(this.getString(R.string.setUp)); builder.setSmallIcon(R.drawable.ic_launcher); builder.setOnlyAlertOnce(true); builder.setAutoCancel(true); //notif = new Notification(R.drawable.ic_launcher, this.getString(R.string.downloadDone), System.currentTimeMillis()); //notif.flags = Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL; try { Intent intent = new Intent(); // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_VIEW); Uri url; if (Build.VERSION.SDK_INT >= 24){ CXLog.e(TAG,"getPackageName()=="+mContext.getApplicationContext().getPackageName()+"//path=="+myTempFile.getAbsolutePath().toString()); url = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", myTempFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//对目标应用临时授权该Uri所代表的文件 }else{ url =Uri.fromFile(myTempFile); } intent.setDataAndType(url, "application/vnd.android.package-archive"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); builder.setContentIntent(pendingIntent); notif = builder.build(); } catch (Exception e) { e.printStackTrace(); } //notif.setLatestEventInfo(this, this.getString(R.string.downloadDone), this.getString(R.string.setUp), pendingIntent); notifiManager.notify(UpdateNotifId, notif);
taskAffinity
taskAffinity总结:是否是同一个任务,如果想在不同任务,可以用这个。
task是在程序运行时,只针对activity的概念。说白了,task是一组相互关联的activity的集合,它是存在于framework层的一个概念,控制界面的跳转和返回。这个task存在于一个称为back stack的数据结构中,也就是说,framework是以栈的形式管理用户开启的activity。这个栈的基本行为是,当用户在多个activity之间跳转时,执行压栈操作,当用户按返回键时,执行出栈操作。举例来说,如果应用程序中存在A,B,C三个activity,当用户在Launcher或Home Screen点击应用程序图标时,启动主Activity A,接着A开启B,B开启C,这时栈中有三个Activity,并且这三个Activity默认在同一个任务(task)中,当用户按返回时,弹出C,栈中只剩A和B,再按返回键,弹出B,栈中只剩A,再继续按返回键,弹出A,任务被移除。如下图所示:
singlerInstance其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。
SingleInstance模式启动的Activity在系统中具有全局唯一性。就是单列的效果
1.MediamainActivity 被重新创建了oncreate方法,前面的所有的activity都没有销毁
standard----每次点击图标或home键的时候重新创建MediamainActivity , MediamainActivity 有多个OnCreate方法执行
2.singleTask:
先进入了MediamainActivity ,再进入了Videoplay的话,点击图标
MediamainActivity 在顶,显示顶端的!
singleTask和其他所有的区别在于:Mediamain只有一个,销毁前面的所有的activity
有一个Mediamain只,执行onNewIntent()和singleInstance一样!
就重用该实例(会调用实例的onNewIntent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈
其他的videoPlay,audioplay,imagePlay都销毁了
3.先进入了MediamainActivity ,再进入了Videoplay的话,点击图标
MediamainActivity 在顶,显示顶端的!和Stander不一样
singleInstance和其他所有的区别在于:Mediamain只有一个,前面的所有的activity都没有销毁
singleInstance(多个应用程序共享一个应用)===比如说:在语音中调用多媒体程序!!
singleTop ,这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,通过此方法的参数我们可以去除当前请求的信息。
如果栈顶不存在该Activity的实例,则情况与standard模式相同
singleTop模式分3种情况
是不是同一个实例:hashcode值
案例分析:
standard,创建一个新的Activity。
singleTop,栈顶不是该类型的Activity,创建一个新的Activity。否则,onNewIntent。
singleTask,回退栈中没有该类型的Activity,创建Activity,否则,onNewIntent+ClearTop。
注意: 1.设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的Task存在; 如果存在这样的Task,它就会在这个Task中启动,否则就会在新的任务栈中启动。
因此, 如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。
2.如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例, 如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity 实例会位于任务的Stack顶端中。
3.在一个任务栈中只有一个”singleTask”启动模式的Activity存在。他的上面可以有其他的Activity。这点与singleInstance是有区别的。
singleInstance,回退栈中,只有这一个Activity,没有其他Activity。
singleTop适合接收通知启动的内容显示页面。 例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。 singleTask适合作为程序入口点。 例如浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。
singleInstance应用场景:闹铃的响铃界面。 你以前设置了一个闹铃:上午6点。在上午5点58分,你启动了闹铃设置界面,并按 Home 键回桌面;在上午5点59分时,你在微信和朋友聊天; 在6点时,闹铃响了,并且弹出了一个对话框形式的 Activity(名为 AlarmAlertActivity) 提示你到6点了(这个 Activity 就是以 SingleInstance 加载模式打开的),你按返回键,回到的是微信的聊天界面,这是因为 AlarmAlertActivity 所在的 Task 的栈只有他一个元素, 因此退出之后这个 Task 的栈空了。如果是以 SingleTask 打开 AlarmAlertActivity,那么当闹铃响了的时候,按返回键应该进入闹铃设置界面。
实例:
Intent flag的重要标志之一: FLAG_ACTIVITY_NEW_TASK
在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,不然会报异常。
private void NotifBar(File myTempFile) { if (notifiManager == null) { notifiManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE); } notifiManager.cancel(UpdateNotifId); if (notif != null) { notif = null; } NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); RemoteViews contentView = new RemoteViews(this.getPackageName(), R.layout.base_download_act); contentView.setTextViewText(R.id.down_tx, this.getString(R.string.downloadDone)); builder.setContentTitle(this.getString(R.string.downloadDone)); builder.setContentText(this.getString(R.string.setUp)); builder.setSmallIcon(R.drawable.ic_launcher); builder.setOnlyAlertOnce(true); builder.setAutoCancel(true); //notif = new Notification(R.drawable.ic_launcher, this.getString(R.string.downloadDone), System.currentTimeMillis()); //notif.flags = Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL; try { Intent intent = new Intent(); // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_VIEW); Uri url; if (Build.VERSION.SDK_INT >= 24){ CXLog.e(TAG,"getPackageName()=="+mContext.getApplicationContext().getPackageName()+"//path=="+myTempFile.getAbsolutePath().toString()); url = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".provider", myTempFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//对目标应用临时授权该Uri所代表的文件 }else{ url =Uri.fromFile(myTempFile); } intent.setDataAndType(url, "application/vnd.android.package-archive"); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); builder.setContentIntent(pendingIntent); notif = builder.build(); } catch (Exception e) { e.printStackTrace(); } //notif.setLatestEventInfo(this, this.getString(R.string.downloadDone), this.getString(R.string.setUp), pendingIntent); notifiManager.notify(UpdateNotifId, notif);
taskAffinity
taskAffinity总结:是否是同一个任务,如果想在不同任务,可以用这个。