【问题标题】:Implicit vs Explicit Intent in Android ( startActivity(intent) crashes )Android中的隐式与显式意图( startActivity(intent) 崩溃)
【发布时间】:2014-02-08 15:12:35
【问题描述】:

我是这个世界上的新人。我在使用 startActivity(intent) 时遇到问题。 这是清单:

<activity
        android:name="com.example.counter.Splash"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <activity
        android:name="com.example.counter.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

这是代码:

 public class Splash extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    setContentView(R.layout.splash);

    Thread timer = new Thread(){
        public void run()
        {
            try
            {
                sleep(5000);

            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            finally
            {

                Intent i=new Intent ("com.example.counter.MainActivity");
                startActivity(i);
            }
        }
    };

    timer.start();

}

我想显示 Splash 活动 5 秒钟,然后显示 MainActivity。 日志错误:!https://www.dropbox.com/s/kg7xyp6h4b95itq/Screenshot%202014-02-08%2016.57.36.png

【问题讨论】:

  • 看看不同的Intent constructors。您正在尝试使用 Intent 启动,该 Intent 的操作不存在,因此出现错误。改用 Intent(android.content.Context, java.lang.Class>)

标签: android android-intent android-activity


【解决方案1】:

有两种方法可以做你想做的事情。

  1. 使用隐式Intent
  2. 使用显式Intent

参考Intent Types

  1. 隐式Intent

在您的AndroidManifest.xml 中为您的Activity 声明Intent Filters。通过这样做,Android 系统了解您的组件(在本例中是您的 MainActivity)可以处理哪种类型的 Intents

<activity
        android:name="com.example.counter.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="com.example.counter.MainAction" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
<activity>

现在您可以使用相同的Intent 启动您的Activity

Intent i=new Intent ("com.example.counter.MainAction");
startActivity(i);

这种隐含的Intents 用于当您不明确知道必须启动哪个 Activity 并且您希望 Android 系统决定启动哪个组件时。如果系统发现多个组件可以处理您的 Intent,它将允许用户选择。

注意:可能没有应用程序可以处理您的意图。在这种情况下,当您调用 startActivity() 时,您的应用程序将崩溃。为了避免这种情况,在调用 startActivity() 之前,您应该首先验证系统中至少有一个注册的应用程序可以处理该意图。为此,请在您的意图对象上使用 resolveActivity()。

  1. 显式Intent

在您的情况下,您应该使用明确的Intent,因为您已经知道要开始哪个Activity。因此,通过传递上下文和您要启动的组件(活动)类来创建一个Intent

Intent i=new Intent (this,MainActivity.class);
startActivity(i);

【讨论】:

    【解决方案2】:

    您必须引用您要启动的class。所以你需要这样的东西:

    Intent newAct = new Intent(this, Splash.class);
    startActivity(newAct);
    

    您传递的是一个Action,它不被理解为类名。

    【讨论】:

    • "com.example.counter.MainActivity" 是一个动作而不是简单的字符串。
    • 没错!修改了我的答案。谢谢。
    • 但存在构造函数公共 Intent(字符串操作)
    • 据我了解,您不想在此处输入action。您想实例化一个代表 Activity 的类。因此,您需要使用我提供的代码。
    【解决方案3】:

    我猜,Splash 是您的 Launcher Activity,请在清单文件中进行以下更改:

    <activity
        android:name="com.example.counter.Splash"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
    
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    
    <activity
        android:name="com.example.counter.MainActivity"
        android:label="@string/app_name" >
    </activity>
    

    以这种方式进行活动:

    public class Splash extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.splash);
    
            /*Splach screen that display for 5 seconds when app start*/
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Intent i = new Intent(Splash.this, MainActivity.class);
                    startActivity(i);
                    finish();
                }
            }, 5000);
    
        }
    
    }
    

    我希望这能解决您的问题。

    【讨论】:

    • 如果处理不当可能会导致巨大的内存泄漏。我建议阅读这篇文章以了解如何在没有内存泄漏危险的情况下获取 Contextstackoverflow.com/questions/7144177/…
    • 还有一个错误。在第一条指令中,这给了我这个问题:“类型不匹配:无法从新线程(){}转换为上下文”
    • 查看我在描述中的链接
    【解决方案4】:

    我认为你应该可以使用(隐式 Intent):

    Intent i=new Intent ("com.example.counter.MainActivity");
    

    没有理由将其更改为(显式意图):

    startActivity(new Intent(mContext, MainActivity.class));
    

    但是您需要将 action in intent filterof MainActivity 更改为:

    <action android:name="android.intent.action.MAIN" />
    

    到:

    <action android:name="com.example.counter.MainActivity"/>
    

    【讨论】:

    • 嘿嘿,没查到有没有类似&lt;action android:name="com.example.counter.MainActivity"/&gt;的动作
    • 有改变的理由:安全问题。例如,在这种情况下,竞争应用程序也可以提供“com.example.counter.MainActivity”意图,并且每次他们打开您的应用程序时,都会询问用户他们想要选择哪个提供程序。隐式意图仅适用于应用程序间服务(例如文档查看器),或与您的应用程序系列中的其他应用程序之间的转换(通过防止非附属应用程序访问的权限来保护它们,除非并且直到您想要使意图成为您与世界的 API 合同的一部分)。
    【解决方案5】:

    你需要在清单文件中declare an activity

    像这样:

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".FirstActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activty
            android:name="com.example.counter.MainActivity"/>
    </application>
    

    希望对你有帮助。

    【讨论】:

      【解决方案6】:

      我认为如果你使用 Handler 将这段代码放在 onCreate 的 splash Activity 中会更好

      new Handler().postDelayed(new Runnable() {
                  @Override
                  public void run() {
                      Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                      startActivity(intent);
                      finish();
                  }
              }, 1500); 
      

      如果你想打开一次,最好使用 SharedPreferences

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-28
        • 1970-01-01
        相关资源
        最近更新 更多