当新的应用实例启动时,如何将数据传递给已经运行的应用实例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当新的应用实例启动时,如何将数据传递给已经运行的应用实例相关的知识,希望对你有一定的参考价值。
我的应用程序架构包括启动画面作为启动器活动。应用程序启动后会破坏启动画面。因此,为了防止重新启动应用程序(因为已经破坏了启动器活动),我在onCreate方法中为启动屏幕添加了这个:
if (!isTaskRoot())
{
finish();
return;
}
因此,如果已经运行实例并且显示了运行实例,则新实例将自行完成。目前很好。但是,新的应用实例并不总是从启动器开始。我已将Firebase Messaging设置为从我的服务器接收推送消息。推送消息包含一些额外的数据,它可以通过这种方式加入:
String messageId = getIntent().getStringExtra("id_message");
单击推送消息通知后启动新的应用程序实例时。如果应用程序已经运行,我需要在推送通知单击(它工作)后显示它,然后处理message_id
已经运行的应用程序实例(新实例应该完成自己)。但我不知道如何将message_id
传递给已经运行的实例,以便能够处理它并显示消息详细信息而无需重新启动整个应用程序。
你有什么主意吗?
您可以使用中间Activity来选择要启动的Activity。
首先,创建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;
}
}
您需要在启动画面活动中设置标志。
第三,将LaunchActivity
设置为AndroidManifest.xml
中的发射器并将其设置为隐藏和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">
最后,您需要在启动splash活动后设置标志:
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函数或工具栏导航内部单击listener.So当用户按下后退按钮时,会创建一个人工堆栈,android会处理其余的。
在androidmanifest.xml中,通过添加以下代码为每个活动分配父活动
android:parentActivityName=".ParentActivityName"
我有几乎相同的问题。我的应用程序从启动器或意图开始。添加启动画面活动后,如果应用程序处于后台,则意图从应用程序启动第二个实例。
我在清单中的两个活动中添加了android:launchMode =“singleTask”,现在它像以前一样工作。一次只能有一个应用实例。
对我没有任何意义,但只要它有效我就不在乎......
以上是关于当新的应用实例启动时,如何将数据传递给已经运行的应用实例的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据传递给嵌套控制器(UIContainerView)?
通过 Segue 将数据传递给新的 ViewController
如何将数据传递给子 UINavigationController?