安卓Intent语法

3

我试图找出如何在我的应用程序中启动新意图,我遇到了几种措辞方式。

这个语法会返回一个运行时错误,即ActivityNotFound异常。

Intent in = new Intent("com.something.something"); 

当然,我的Android清单包含意图过滤器内的一个操作:
<activity
        android:name=".SecondActivity"
        android:label="@string/title_activity_second" >
        <intent-filter>
            <action android:name="com.something.something" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity> 

这种格式是可行的:

Intent in = new Intent(MainActivity.this, SecondActivity.class); 

我还尝试了以下方法:

Intent in = new Intent(this, SomeActivity.class); 

在我正在阅读的一本书中,推荐了一个解决方案来解决这个问题。但是运行后返回了一个“activitynotfound”的错误。

以下方法会让Eclipse在setClass和setClassName之间无限循环:

 Intent in = new Intent().setClass(this, SecondActivity.class);

我在一个onclick方法中使用它:

ok.setOnClickListener(new View.OnClickListener()
    {

        @Override
        public void onClick(View v)
        {

            Intent in = new Intent(MainActivity.this, SecondActivity.class);
            startActivity(in);
        }
    });
}

这两者之间有什么区别,为什么只有其中一个对我有效?
敬礼 /M
2个回答

11

关于Intent解析的基本信息

Intents可以包含以下基本信息:

  • ACTION(操作)
  • CATEGORY(类别)
  • DATA(数据)
  • COMPONENT(组件)

系统通过以下2种方式解析Intents:

  • 显式解析(如果指定了组件,则使用组件)
  • 隐式解析(使用操作、类别和数据查找合适的活动)

如果您指定了组件(包名和类名),则会使用它来显式地查找您指定的活动,并将Intent发送到该活动。其他Intent数据不会被使用(虽然它会传递给调用的活动)。这被称为“显式Intent解析”

如果您没有指定组件,则使用ACTION、CATEGORY和DATA字段来定位一个或多个广告(通过意图过滤器)可以接受Intent的活动。这被称为“隐式Intent解析”


针对您的具体问题

当您执行以下操作时:

Intent in = new Intent("com.something.something");

您正在创建一个隐式Intent,并将ACTION设置为“com.something.something”。如果您使用此Intent调用startActivity(),则会收到ActivityNotFoundException,因为Android找不到可以接受ACTION =“com.something.something”的Intent的活动。原因是您已经提供了一个intent-filter,其中ACTION =“com.something.something”和CATEGORY =“android.intent.category.LAUNCHER”,但在Intent中没有指定CATEGORY(当使用startActivity()时,Android会自动向Intent添加CATEGORY“DEFAULT” ,如果没有指定任何CATEGORY)。要使其工作,您应该执行以下操作之一:

  • CATEGORY =" android.intent.category.LAUNCHER "替换为CATEGORY =" android.intent.category.DEFAULT "
  • SecondActivity的intent-filter添加<category android:name="android.intent.category.DEFAULT" />


当你这样做时:
Intent in = new Intent(MainActivity.this, SecondActivity.class);

您正在创建一个指定组件SecondActivity显式Intent。该方法的签名为Intent(Context packageContext, Class clas)。它使用packageContext中的包名称和clas中的类名称为该组件创建显式Intent。如果您在Activity内部使用此构造函数,您可以将this作为第一个参数,因为Activity扩展了Context。如果您从另一个类(如OnClickListener)中使用此构造函数,则需要将MyActivity.this指定为第一个参数,以传递Activity的实例而不是OnClickListener的实例(因为OnClickListener没有扩展Context)。
当您执行以下操作时:
Intent in = new Intent().setClass(this, SecondActivity.class);

你正在创建一个明确的Intent,如上所述。这与使用以下内容完全相同:
Intent in = new Intent(this, SecondActivity.class);

你不能在 OnClickListener 中这样做,因为第一个参数需要是一个 Context(或者是继承自 Context 的类,比如 Activity)。

如果你想创建一个 显式 Intent,你也可以使用以下代码:

Intent in = new Intent().setClassName("com.something", "com.something.SecondActivity");

这创建了一个明确的意图,但您不需要为此使用上下文。您只需将包名称和类名称作为字符串传递即可(如果您知道它们)。
有关意图解析的更多信息,请参见:

0
请注意,在使用“Intent in = new Intent(this, SomeActivity.class);”中的“this”关键字时,请确保您不在MainActivity的子类中,否则可能会将错误的Activity设置为显式意图组件的一部分。

实际上,这是无关紧要的。Intent 构造函数的第一个参数签名为 (Context, Class),只使用 Context 参数获取包名。因此,您可以使用应用程序的任何 Context,这将完美地工作。显式 IntentActivity 由第二个参数设置。 - David Wasser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接