【问题标题】:Android Home activity launching a sub-activityAndroid Home 活动启动子活动
【发布时间】:2011-06-21 15:39:55
【问题描述】:

我对 Android 编程比较陌生。我在工作中被分配了一项任务,我需要创建一个自定义主页活动启动器。我做了一些研究,在 Android 开发者网站 (home sample) 上找到了这个例子。这是我的原型的开始。

自定义 Home 活动将需要用户进行身份验证(输入一些简单的凭据)。我的想法是从 Home 活动启动一个子活动,并将意图中的结果传递回 Home 活动。我需要能够捕获有关这些凭据的信息,并且该信息将被传递回 Home 活动。但是,我在尝试这个时遇到了问题。我在 LogCat 中收到一条日志,内容如下:“活动正在作为新任务启动,因此取消活动结果。”

我知道 startActivityForResult 方法,但这似乎对我不起作用。这是我从 Home 活动启动活动的地方:

@Override
protected void onResume() {
    super.onResume();
    bindRecents();

    Intent iii = new Intent(this, Login.class);
    startActivityForResult(iii, STATIC_LOGIN_INTEGER_VALUE);
}

当该代码执行时,我从 ActivityManager 标记中获取上述日志。

我的登录活动有一个按钮,用户在输入凭据后会点击该按钮。如果凭据是好的,那么我尝试执行以下操作(我输入了几个日志,以便尝试找出发生了什么):

public void onClick(View src) {
    // check for authentic credentials
    if(IsValid())
    {
        Intent loginAuth = new Intent("Login");
        loginAuth.putExtra("userRole", userRole);

        Log.d("LOGIN", "Setting result...");
        if (getParent() == null) {
            Log.d("LOGIN", "Parent was null");
            setResult(Activity.RESULT_OK, loginAuth);
        }
        else {
            Log.d("LOGIN", "setting result on parent...");
            getParent().setResult(Activity.RESULT_OK, loginAuth);
        }

        Log.d("LOGIN", "Finishing the activity");
        finish();
    }
}

我在清单文件中将这些活动定义如下:

    <activity android:name="Home"
            android:theme="@style/Theme"
            android:launchMode="singleInstance"
            android:stateNotNeeded="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME"/>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <activity android:name="Login"
              android:label="Login"
              android:launchMode="singleInstance">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME" />
        </intent-filter>
    </activity>

我正在使用登录活动的意图过滤器。我最初将其设置为空。我也有 launchMode 空白(我相信默认为标准)。我已经使用了大多数这些选项,但似乎没有什么可以改变 ActivityManager 似乎想要将活动作为新任务启动并想要忽略返回的意图(我需要)这一事实。

【问题讨论】:

    标签: android android-activity android-launcher android-homebutton subactivity


    【解决方案1】:

    问题在于您使用 launchMode="singleInstance" 声明了您的活动,因此 Android 在启动登录活动时会创建一个新任务(即新进程)。不同任务中的活动不能互相返回结果。来自 Activity.startActivityForResult() 文档:

    例如,如果您从事的活动 启动使用 singleTask 启动 模式,它不会在您的任务中运行,并且 因此您将立即收到一个 取消结果。

    singleInstance 与 singleTask 类似,但更具限制性。尝试从清单中删除 launchMode 属性,以便登录活动将在同一任务中启动,然后在需要在单独任务中启动不同活动时使用 FLAG_ACTIVITY_NEW_TASK。

    巴里

    【讨论】:

    • 感谢您的回答。更改启动模式对我没有任何帮助,直到我也更改了 Home 活动启动模式。我需要做更多的挖掘来找出正确的组合。我们绝对不希望这些推出的多项活动。现在我正在使用 singleTop 而不是标准。我认为我需要更多地使用这些标志来启动这些活动。现在,我只是使用 singleTop 来调试/开发我需要的其他功能。我稍后会重新访问。我正在快速了解清单文件的强大功能;)
    【解决方案2】:

    文档说

    例如,如果您正在启动的活动使用 singleTask 启动模式,它不会在您的任务中运行,因此您将 立即收到取消结果。

    这是错误的

    singleTask可以用,不能用singleInstance

    让我们回到问题上来。有什么问题?

    问题是当你在一个活动上调用startActivityForResult()时,调用者活动和你正在启动的活动必须在同一个任务上,startActivityForResult()才能正常工作,这意味着你不能 使用 Intent.FLAG_ACTIVITY_NEW_TASK 调用 startActivityForResult()。

    为什么 singleInstance 不起作用?

    因为“singleInstance”活动是其任务中唯一的活动。如果它启动另一个活动,则无论其启动模式如何,该活动都将启动到不同的任务中——就好像 FLAG_ACTIVITY_NEW_TASK 在意图中一样。在所有其他方面,“singleInstance”模式与“singleTask”相同。

    为什么 singleTask 有效?

    因为 singleTask 不需要为正在启动的新活动创建新任务。

    我引用this answer来解释两种启动模式的区别。

    【讨论】:

      【解决方案3】:

      您是否在登录活动中声明了setResult(int resultCode, Intent data)。 Android 文档说 “请注意,此方法只能与定义为返回结果的 Intent 协议一起使用。”如果不匹配或与Activity.startActivityForResult() 文档中的某些其他条件匹配,它将不会在您的任务中运行,因此您将立即收到取消结果。”

      【讨论】:

      • 我确实在上面的代码示例中声明了这一点(在 onClick 处理程序中)。原来这是由于清单文件中的启动模式。我很快了解到清单文件可以创建/破坏应用程序:)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多