【问题标题】:Launch application from statusbar without re-creation从状态栏启动应用程序而无需重新创建
【发布时间】:2013-03-05 18:36:59
【问题描述】:

我正在创建在状态栏中显示通知图标的应用程序。当用户打开状态栏并点击图标时,应启动应用程序。

我正在寻找一种方法来避免在此次发布期间重新创建应用程序。我创建了测试应用程序并将日志消息添加到处理程序 onCreate、onRestart、onResume、onStop 和 onDestroy。日志消息说明了问题:

  1. 用户启动应用程序 - onCreate、onResume
  2. 用户按下 HOME 按钮 - onStop
  3. 用户打开应用程序列表并再次启动应用程序 - onRestart、onResume
  4. 用户按下 HOME 按钮 - onStop
  5. 用户打开最近应用程序列表并选择应用程序 - onRestart、onResume
  6. 用户按下 HOME 按钮 - onStop
  7. 用户打开状态栏并点击应用程序图标 - onDestroy、onCreate、onResume。

步骤 7 的行为与 3) 和 5) 不同 - 这里有 onDestroy。换句话说,应用程序的实例被重新创建。有没有可能避免这种消遣?

这是我的测试活动的代码:

public class MainActivity extends Activity {
    private final String LOG_TAG = "com.example.notificationtest";

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        showNotification(this);
        Log.d(LOG_TAG, "NotificationTest: OnCreate");
    }

    @Override protected void onRestart() {
        super.onRestart();
        Log.d(LOG_TAG, "NotificationTest: OnRestart");
    }

    @Override protected void onResume() {
        super.onResume();
        Log.d(LOG_TAG, "NotificationTest: OnResume");
    }

    @Override protected void onDestroy() {
        super.onDestroy();
        Log.d(LOG_TAG, "NotificationTest: OnDestroy");
    }

    @Override protected void onStop() {
        super.onStop();
        Log.d(LOG_TAG, "NotificationTest: OnStop");
    }


    private static final int NOTIF_ID = 91371;

    public static void showNotification(Context context) {
        final Intent result_intent = new Intent(context, MainActivity.class);
        result_intent.setAction(Intent.ACTION_MAIN);
        result_intent.addCategory(Intent.CATEGORY_LAUNCHER);
        //result_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //result_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        //result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);                

        TaskStackBuilder stack_builder = TaskStackBuilder.create(context);
        stack_builder.addParentStack(MainActivity.class);
        stack_builder.addNextIntent(result_intent);

        PendingIntent pending_intent = stack_builder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

        android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(context);

        Resources res = context.getResources();
        builder.setContentIntent(pending_intent)
            .setSmallIcon(R.drawable.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
            .setTicker("test")
            .setWhen(System.currentTimeMillis())
            .setAutoCancel(false)
            .setContentTitle("title")
            .setContentInfo("cinfo")
            .setContentText("ctext");
        Notification n = builder.build();
        n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;   

        NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(NOTIF_ID, n);     
    }
}

有一些标志可以设置为 result_intent,例如 FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_NEW_TASK。它们允许指定应在启动时重新启动活动(使用活动启动模式“singleTop”、“singleTask”等)。但是应该设置什么标志以避免重新启动?也许我应该以某种方式配置pending_intent?

任何帮助将不胜感激。

已解决

非常感谢解答,问题解决了。

here 描述了同样的问题。我已经从该主题检查了测试项目,发现与我的代码不同。为了解决这个问题,我的代码应该按以下方式更改:

final Intent result_intent = new Intent(context, MainActivity.class);
//result_intent.setAction(Intent.ACTION_MAIN); // (1)
//result_intent.addCategory(Intent.CATEGORY_LAUNCHER); // (2)
result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

另一组标志也可以:

result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 

重点是注释第 (1) 和 (2) 行

【问题讨论】:

  • onSaveInstanceState()onRestoreInstance() 被调用了吗?比试图绕过活动生命周期更好的选择可能是通过这些方法恢复基本的运行数据,这将使您存储的数据在 onDestroy 中持久化。
  • 查看这篇 SO 帖子:stackoverflow.com/questions/3305088/…
  • 是的,调用了 onSaveInstanceState() 和 onRestoreInstance()。我不尝试解决生命周期。问题的根源在这里描述:forum.unity3d.com/threads/…
  • 致appsroxcom:非常感谢!问题出在 addCategory(Intent.CATEGORY_LAUNCHER) 和 setAction(Intent.ACTION_MAIN)

标签: android


【解决方案1】:

添加这个:

result_intent..setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                                    | Intent.FLAG_ACTIVITY_NEW_TASK);

它像

Intent.FLAG_ACTIVITY_REORDER_TO_FRONT

还维护活动堆栈

【讨论】:

  • 谢谢,但没有结果。看起来行为不依赖于一组意图标志:(
  • 更正:如果我评论 Intent.ACTION_MAIN 和 CATEGORY_LAUNCHER,这组标志可以正常工作,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多