有没有办法让每个活动只有一个实例?

时间:2012-01-24 23:44:23

标签: android android-manifest android-activity

我发现在我的应用程序中,用户可以在用户使用应用程序时打开的各种活动中完全“嵌套”。

例如:

  1. 主菜单
  2. 对象列表
  3. 对象详细信息
  4. 对象编辑
  5. 对象详细信息
  6. 对象子级详细信息
  7. 对象子编辑
  8. 对象子级详细信息
  9. 现在,当用户按下时,它必须经过两次“对象子细节”(同一个对象,当它被编辑时返回到详细页面),同样的事情发生在'父对象细节'上

    有没有办法重用活动,如果它们已经在堆栈中打开,并将它们重新排序到前面?我看到的唯一方法是使用launcher属性的活动。我相信我看到singleTasksingleTop

    如果我应该使用这两个属性singleTasksingleTop,我应该如何使用它们?当我试图将它们包含在应用程序中时,它没有任何区别。使用startActivity启动意图时是否还需要设置标记?

9 个答案:

答案 0 :(得分:40)

在Manifest Activity属性中,您可以提供此参数android:launchMode="singleInstance"

在此处详细阅读http://developer.android.com/guide/topics/manifest/activity-element.html

答案 1 :(得分:25)

这是你的旗帜! http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_REORDER_TO_FRONT

intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)

请注意'addFlags'。另请注意,当向其传递新的Intent时,不会在此Activity上调用onCreate。它将通过onNewIntent()发送。

这不能确保活动的单个实例正在运行。为确保这一点,请查看:http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

答案 2 :(得分:25)

使用 android:launchMode =“singleTask”可能是最好的方法,因为如果活动已经在运行,它将不会重新创建活动。只需将其添加到AndroidManifest.xml中的活动中,您就应该全部设置。

<activity
    android:name=".MyActivity"
    android:label="@string/app_name"
    android:launchMode="singleTask"
    >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
 </activity>

这是另一个可能有用的问题:Android singleTask or singleInstance launch mode?

答案 3 :(得分:7)

是的,您只能要求创建这些活动的一个实例,但通常不建议这样做。如果您只是关注历史,请查看Intent.FLAG_ACTIVITY_CLEAR_TOP

答案 4 :(得分:7)

这对我有用。

Intent intent = new Intent(this, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);

如果此活动的实例已存在,则会将其移至前端。如果实例不存在,将创建一个新实例。

答案 5 :(得分:1)

将意图标志添加为

Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); StartActivity(srcActivity.java, DesiredActivity.class);

然后在onPause() DesiredActivity

添加finish(), 这为我做了工作。

答案 6 :(得分:0)

public class ScaleoutMessageBus : Microsoft.AspNet.SignalR.Messaging.ScaleoutMessageBus
      {
        private static long sNextId = long.MinValue;
        private readonly List<string> proxiesEndpointName;
        private static readonly object Lock = new object();

        /// <summary>
        ///   Initializes a new instance of the <see cref="ScaleoutMessageBus" /> class.
        /// </summary>
        /// <param name="resolver">The resolver.</param>
        /// <param name="config">The configuration.</param>
        public ScaleoutMessageBus(IDependencyResolver resolver, ScaleoutConfiguration config)
          : base(resolver, config)
        {
          proxiesEndpointName = new List<string>(config.NodeEndpoints);
          Open(0);
        }

        private void Received(int streamIndex, long id, byte[] data)
        {
          ScaleoutMessage message = ScaleoutMessage.FromBytes(data);
          var uid = unchecked((ulong)id);
          lock (Lock)
          {
            OnReceived(streamIndex, uid, message);
          }
        }

        /// <summary>
        /// Sends the specified stream index.
        /// </summary>
        /// <param name="streamIndex">Index of the stream.</param>
        /// <param name="messages">The messages.</param>
        /// <returns></returns>
        protected override Task Send(int streamIndex, IList<Message> messages)
        {
          var messageToSend = new ScaleoutMessage(messages);
          var bytesToSend = messageToSend.ToBytes();
          return Task.Factory.StartNew(() =>
          {
            Parallel.ForEach(proxiesEndpointName.Where(s => !String.IsNullOrEmpty(s)), s =>
            {
              try
              {
                var proxy = new ChannelProxyWrapper<IBackplaneService>(s).GetTransparentProxy();
                proxy.Send(streamIndex, bytesToSend);
              }
              catch (Exception ex)
              {
                LogHelper.WriteException(ex, TraceEventType.Warning, "Cannot send message to node {0}", s);
              }
            });
          });
        }


        /// <summary>
        /// Sends the specified stream index.
        /// </summary>
        /// <param name="streamIndex">Index of the stream.</param>
        /// <param name="data">The data.</param>
        public void Send(int streamIndex, byte[] data)
        {
          long id = Interlocked.Increment(ref sNextId);
          Received(streamIndex, id, data);
        }
      }

它对我有用:)

答案 7 :(得分:0)

我只想拥有一个MainActivity实例,但是当我添加时:

launchMode="singleInstance"
在我的清单中,

出现一个白屏,所以我从清单中删除了SingleInstance代码。 我在MainActivity类中添加了MainActivity的两个公共静态变量:

public static MainActivity mainActivity_instance = null;
public static MainActivity mainActivity_OldInstance = null;

然后我将以下代码添加到onCreate():

 if(mainActivity_instance != null)//if true, it means there was an instance of mainActivity before and it had to be closed.
        mainActivity_OldInstance = mainActivity_instance;
    mainActivity_instance = this;
 if(mainActivity_OldInstance != null)
        mainActivity_OldInstance.finish();

如您所见,我完成了MainActivity的先前实例,就像创建了新实例一样!

答案 8 :(得分:0)

在科特林中:

fun AppCompatActivity.startSingleActivity(intent: Intent) {
    startActivity(intent.apply {
        flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
    })
}