繁体   English   中英

启动新的应用程序实例时,如何将数据传递到已运行的应用程序实例

[英]When new app instance launched, how to pass data to already running app instance

我的应用程序体系结构包括启动屏幕作为启动器活动。 启动应用程序后,启动画面被破坏。 因此,为防止重新启动应用程序(由于启动器活动被破坏),我在启动屏幕的onCreate方法中添加了此代码:

if (!isTaskRoot())
{
  finish();
  return;
}

因此,如果已经存在正在运行的实例并显示正在运行的实例,则新实例将自行完成。 目前很好。 但是,新的应用程序实例并非总是从启动器启动。 我已将Firebase Messaging设置为从服务器接收推送消息。 推送消息包含一些其他数据,可以通过以下方式访问:

String messageId = getIntent().getStringExtra("id_message");

单击推送消息通知后启动新的应用程序实例时。 如果应用程序已经在运行,我需要在推送通知单击后显示它(它可以工作),然后使用已经运行的应用程序实例处理message_id (新实例应自行完成)。 但是我不知道如何将message_id传递给已经运行的实例,以便能够处理它并显示消息详细信息而无需重新启动整个应用程序。

你有什么主意吗?

您可以使用中间活动来选择要启动的活动。

首先 ,创建LaunchActivity

public class LaunchActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.empty);

     BaseApp application = (BaseApp) this.getApplication();

    // determine where to go
    if(application.isHasGoToMain()) {
      Intent intent = new Intent(this, MainActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      finish();
      startActivity(intent);
    } else {
      Intent intent = new Intent(this, SplashScreenActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      finish();
      startActivity(intent);
    }
  }
}

empty布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone">

</LinearLayout>

其次 ,如果主要活动已经启动,则创建一个应用程序进行保存:

public class BaseApp extends Application {
  private boolean hasGoToMain = false;

  public boolean isHasGoToMain() {
    return hasGoToMain;
  }

  public void setHasGoToMain(boolean hasGoToMain) {
    this.hasGoToMain = hasGoToMain;
  }
}

您需要在初始屏幕活动中设置标志。

第三 ,在AndroidManifest.xml中将LaunchActivity设置为启动器,并将其设置为hidden和singleTask

<activity
    android:name=".LaunchActivity"
    android:screenOrientation="portrait"
    android:configChanges="orientation"
    android:launchMode="singleTask"
    android:theme="@android:style/Theme.NoDisplay"
    android:windowSoftInputMode="stateHidden">
  <intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
  </intent-filter>
</activity>

第四 ,您还需要将启动屏幕和主要活动创建为singleTask

<activity
    android:name=".SplashScreenActivity"
    android:launchMode="singleTask"
    android:configChanges="screenSize|orientation|screenLayout">

</activity>

<activity
    android:name=".MainActivity"
    android:launchMode="singleTask"
    android:label="@string/app_name"
    android:theme="@style/AppThemeMain.NoActionBar">

最后 ,您需要在启动启动活动之后设置标志:

public class SplashScreenActivity extends AppCompatActivity {
  ...
  @Override 
  protected void onCreate(Bundle savedInstanceState) {
    ...

    BaseApp baseApp = (BaseApp) this.getApplication();
    baseApp.setHasGoToMain(true);
  }
}

现在,您可以发送意图并在主活动的onNewIntent()中处理它。

首先在清单文件中的活动标签中添加启动模式,例如

<activity
android:name="your_activity_name"
android:launchMode="singleTop" /> 

当您单击通知并且您开始任何活动时

如果您的活动不存在,那么将开始新的活动。 如果该活动已经打开,则将调用其onNewIntent(Intent intent),您将收到在此intent参数中发送的数据。

当从Firebase收到应用程序中的推送时,它将由MyFirebaseMessagingService处理。 在那儿,您需要创建一个挂起的意图,即当用户点击通知时需要打开的活动。

Intent resultIntent = new Intent(context, ActivityToOpen.class);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addNextIntentWithParentStack(resultIntent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, 
  PendingIntent.FLAG_UPDATE_CURRENT);

用户单击通知后,他们将被转到活动ActivityToOpen 。在该活动中,您可以输入以下代码

 Intent upIntent = 
 NavUtils.getParentActivityIntent(ActivityToOpenOnBackPress.this);
        if (NavUtils.shouldUpRecreateTask(CurrentActivityName.this, 
  upIntent)) 
       {

            TaskStackBuilder.create(CurrentActivityName.this)
                    .addNextIntentWithParentStack(upIntent)
                    .startActivities();
        } else {
            NavUtils.navigateUpTo(CurrentActivityName.this, upIntent);
        }

将此代码放在onBackPressed函数中或工具栏导航单击侦听器中。因此,当用户按下后退按钮时,将创建一个人工堆栈,而android会处理其余部分。

在androidmanifest.xml中,通过添加以下代码为每个活动分配一个父活动
android:parentActivityName=".ParentActivityName"

我有几乎相同的问题。 我的应用程序从启动器或意图启动。 添加启动画面活动后,如果应用程序处于后台,则意图从该应用程序启动第二个实例。

我在清单中的两个活动中都添加了android:launchMode =“ singleTask”,现在它像以前一样工作。 一次仅一个应用程序实例。

对我来说没有任何意义,但只要有效,我就不在乎...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM