引入新类后,Android应用程序无法加载

时间:2014-06-18 15:18:15

标签: android

你好,慢慢地爬进这个Android世界并遵循android bootcamp练习2012版。我只能使用一个布局和一个类在AVm上测试我的应用程序但是在引入第二个类,第二个布局和编码按钮时,应用程序无法打开并且日志cat错误看起来像这样

06-18 17:22:29.461: D/AndroidRuntime(542): Shutting down VM
06-18 17:22:29.461: W/dalvikvm(542): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
06-18 17:22:29.471: E/AndroidRuntime(542): FATAL EXCEPTION: main
06-18 17:22:29.471: E/AndroidRuntime(542): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.helloworld/com.example.helloworld.Main}: java.lang.NullPointerException
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.ActivityThread.access$600(ActivityThread.java:122)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.os.Handler.dispatchMessage(Handler.java:99)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.os.Looper.loop(Looper.java:137)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.ActivityThread.main(ActivityThread.java:4340)
06-18 17:22:29.471: E/AndroidRuntime(542):  at java.lang.reflect.Method.invokeNative(Native Method)
06-18 17:22:29.471: E/AndroidRuntime(542):  at java.lang.reflect.Method.invoke(Method.java:511)
06-18 17:22:29.471: E/AndroidRuntime(542):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-18 17:22:29.471: E/AndroidRuntime(542):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-18 17:22:29.471: E/AndroidRuntime(542):  at dalvik.system.NativeStart.main(Native Method)
06-18 17:22:29.471: E/AndroidRuntime(542): Caused by: java.lang.NullPointerException
06-18 17:22:29.471: E/AndroidRuntime(542):  at com.example.helloworld.Main.onCreate(Main.java:24)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.Activity.performCreate(Activity.java:4465)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
06-18 17:22:29.471: E/AndroidRuntime(542):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
06-18 17:22:29.471: E/AndroidRuntime(542):  ... 11 more

这是main.java

public class Main extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button b = (Button)findViewById(R.id.btnPlay);
        b.setOnClickListener(new OnClickListener() {
                @Override

            public void onClick(View v) {
                startActivity(new Intent(Main.this, Recipe.class));
                // TODO Auto-generated method stub
            }

        });

        if (savedInstanceState == null) {
             getFragmentManager().beginTransaction()
                     .add(R.id.container, new PlaceholderFragment())
                     .commit();
         }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
     }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       // Handle action bar item clicks here. The action bar will
       // automatically handle clicks on the Home/Up button, so long
       // as you specify a parent activity in AndroidManifest.xml.

       int id = item.getItemId();
       if (id == R.id.action_settings) {
            return true;
     }
     return super.onOptionsItemSelected(item);

     }

     /**
       * A placeholder fragment containing a simple view.
      */

    public static class PlaceholderFragment extends Fragment {
        public PlaceholderFragment() {}

        @Override
       public View onCreateView(LayoutInflater inflater, ViewGroup container,
               Bundle savedInstanceState) {
              View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
          }
      }
    }

这是新课程

package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;

public class Recipe extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.recipe);

    }

}

这是清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.helloworld.Main"
            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="Recipe"></activity>
    </application>

</manifest>

activity_main

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.helloworld.Main"
    tools:ignore="MergeRootFrame" />

fragment_main

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.helloworld.Main$PlaceholderFragment" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="28dp"
        android:text="@string/mduduzi_games"
        android:textSize="30sp" />

    <Button
        android:id="@+id/btnPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="28dp"
        android:text="@string/play" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="27dp"
        android:src="@drawable/anim4" />

</RelativeLayout>

3 个答案:

答案 0 :(得分:1)

在堆栈跟踪中,Main.java的第24行有一个NullPointerException

at com.example.helloworld.Main.onCreate(Main.java:24)

这是你的问题:

 Button b = (Button)findViewById(R.id.btnPlay);
 //b is null, so the next line throws a NullPointerException:
 b.setOnClickListener(...

b为null,表示activity_main.xml

中没有ID为“btnPlay”的Button

检查以确保在activity_main.xml

中有类似内容
<Button 
    android:layout_width="wrap_content"
    android:text="Some text"
    android:id="@+id/btnPlay"
    android:layout_height="wrap_content" />

编辑:

您正在findViewById致电ActivityViews正在Activity activity_main.xml定义Fragment。由于您已在Fragment布局中定义了按钮,因此您必须在Button代码中获得对按钮的引用。从Activity课程中删除Fragment代码,并将其粘贴到public static class PlaceholderFragment extends Fragment { public PlaceholderFragment() {} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); //find your Button view in rootView Button b = (Button)rootView.findViewById(R.id.btnPlay); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(Main.this, Recipe.class)); // TODO Auto-generated method stub } }); return rootView; } }

{{1}}

答案 1 :(得分:0)

当您走在正确的道路上时,您需要在清单中略微更改一条线。尝试:

<activity android:name="com.example.helloworld.Recipe"></activity>

而不是

<activity android:name="Recipe"></activity>

编辑:实际上,这似乎不是您的当前问题的根源,但是一旦您当前{{1}将成为未来问题的根源是固定的。如其他答案中所述,它会处理您设置为导航到新活动的按钮。

答案 2 :(得分:0)

问题是你的片段布局中定义了btnPlay,但是在片段添加到活动之前,你试图在你的Activity中找到它。

当您致电findViewById(R.id.btnPlay);时,您的活动布局中唯一添加的内容是activity_main,其中只包含一个FrameLayout。在您调用

之前,包含btnPlay的片段不存在
getFragmentManager().beginTransaction()
    .add(R.id.container, new PlaceholderFragment())
    .commit();

一种解决方案是将上述三行移至Button b = (Button)findViewById(R.id.btnPlay);之前。

但是,从活动中引用片段中定义的视图通常是一种不好的做法,因为它是一个非常差的关注点分离。您的Fragment应该处理用户与属于该Fragment的Views的交互,并且您的Activity应该只关注Activity的布局中定义的Views。