繁体   English   中英

无法以意图启动活动

[英]Unable to start activity with intent

我正在学习Android开发。 我在LogCat中遇到问题,似乎无法启动设置活动:

05-06 09:40:37.323: E/AndroidRuntime(945): FATAL EXCEPTION: main
05-06 09:40:37.323: E/AndroidRuntime(945): Process: com.androiddevbook.onyourbike_chapter4, PID: 945
05-06 09:40:37.323: E/AndroidRuntime(945): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androiddevbook.onyourbike_chapter4/com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.ActivityThread.access$800(ActivityThread.java:144)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.os.Handler.dispatchMessage(Handler.java:102)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.os.Looper.loop(Looper.java:135)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.ActivityThread.main(ActivityThread.java:5221)
05-06 09:40:37.323: E/AndroidRuntime(945):  at java.lang.reflect.Method.invoke(Native Method)
05-06 09:40:37.323: E/AndroidRuntime(945):  at java.lang.reflect.Method.invoke(Method.java:372)
05-06 09:40:37.323: E/AndroidRuntime(945):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
05-06 09:40:37.323: E/AndroidRuntime(945):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
05-06 09:40:37.323: E/AndroidRuntime(945): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
05-06 09:40:37.323: E/AndroidRuntime(945):  at com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity.setupActionBar(SettingsActivity.java:48)
05-06 09:40:37.323: E/AndroidRuntime(945):  at com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity.onCreate(SettingsActivity.java:40)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.Activity.performCreate(Activity.java:5933)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
05-06 09:40:37.323: E/AndroidRuntime(945):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
05-06 09:40:37.323: E/AndroidRuntime(945):  ... 10 more

下面是使用函数clickedSettings调用SettingsActivity.class Activity的类(在运行时单击屏幕顶部actionBar上的Settings):

package com.androiddevbook.onyourbike_chapter5.activities;


import com.androiddevbook.onyourbike_chapter4.BuildConfig;
import com.androiddevbook.onyourbike_chapter4.R;
import com.androiddevbook.onyourbike_chapter5.model.TimerState;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.os.Vibrator;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class TimerActivity extends ActionBarActivity {

    private static String CLASS_NAME;
    protected TextView counter;
    protected Button start;
    protected Button stop;

    protected Handler handler;
    protected UpdateTimer updateTimer;
    private static long UPDATE_EVERY = 200;

    protected Vibrator vibrate;
    protected long lastSeconds;

    private TimerState timer;

    public TimerActivity(){
        CLASS_NAME = getClass().getName();
        timer = new TimerState();
    }

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

        counter = (TextView) findViewById(R.id.timer);
        start   = (Button) findViewById(R.id.start_button);
        stop    = (Button) findViewById(R.id.stop_button);

        Log.d(CLASS_NAME, "Setting text.");

        if (BuildConfig.DEBUG){
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().penaltyDeath().build());
        }

        timer.reset();

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Log.d(CLASS_NAME, "Showing 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) {
            Log.d(CLASS_NAME, "SETTINGS PRESSED.");
            System.out.println("Settings pressed.");
            clickedSettings(null);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public void clickedStart(View view){
        Log.d(CLASS_NAME, "Clicked start button.");


        timer.start();
        enableButtons();

        handler = new Handler();
        updateTimer = new UpdateTimer();
        handler.postDelayed(updateTimer, UPDATE_EVERY);
    }

    public void clickedStop(View view){
        Log.d(CLASS_NAME, "Clicked stop button.");


        timer.stop();
        enableButtons();

        handler.removeCallbacks(updateTimer);
        updateTimer = null;
        handler = null;
    }

    public void enableButtons(){

        Log.d(CLASS_NAME, "Set buttons enabled/disabled.");
        start.setEnabled(!timer.isRunning());
        stop.setEnabled(timer.isRunning());
    }



    public class UpdateTimer implements Runnable {

        public void run(){
            Log.d(CLASS_NAME, "run");

            setTimeDisplay();
            if ( handler != null){
                handler.postDelayed(this, UPDATE_EVERY);
            }

            if ( timer.isRunning() ){
                vibrateCheck();
            }
        }

    }

    public void onStart(){
        super.onStart();
        Log.d(CLASS_NAME, "onStart");

        if ( timer.isRunning() ){
            handler = new Handler();
            updateTimer = new UpdateTimer();
            handler.postDelayed(updateTimer, UPDATE_EVERY);
        }

        vibrate = (Vibrator) getSystemService(VIBRATOR_SERVICE);

        if (vibrate == null){
            Log.w(CLASS_NAME, "No vibrate service exists.");
        }

    }

    public void onPause(){
        super.onPause();
        Log.d(CLASS_NAME, "onPause");
    }

    public void onResume(){
        super.onResume();
        Log.d(CLASS_NAME, "onResume");
    }

    public void onStop(){
        super.onStop();
        Log.d(CLASS_NAME, "onSop");

        if ( timer.isRunning() ){
            handler.removeCallbacks(updateTimer);
            handler = null;
            updateTimer = null;
        }

    }

    public void onDestroy(){
        super.onDestroy();
        Log.d(CLASS_NAME, "onDestroy");
    }

    public void onRestart(){
        super.onRestart();
        Log.d(CLASS_NAME, "onRestart");
    }

    protected void vibrateCheck(){

        long diff = timer.elapsedTime();
        long seconds = diff / 1000;
        long minutes = seconds / 60;
        seconds = seconds % 60;
        minutes = minutes % 60;

        Log.d(CLASS_NAME, "vibrateCheck");

        if ( vibrate != null && seconds == 0 && seconds != lastSeconds){
            long[] once = { 0, 100 };
            long[] twice= { 0, 100, 400, 100};
            long[] thrice = { 0, 100, 400, 100, 400, 100 };

            // every hour
            if ( minutes == 0){
                Log.d(CLASS_NAME, "Vibrate 3 times");
                vibrate.vibrate(thrice, -1);
            } 
            // every 15 minutes
            else if ( minutes % 15 == 0 ){
                Log.d(CLASS_NAME, "Vibrate 2 times");
                vibrate.vibrate(twice, -1);
            }
            // every 1 minute
            else if ( minutes == 1 ){
                Log.d(CLASS_NAME, "Vibrate 1 time");
                vibrate.vibrate(once, -1);
            }
        }

        lastSeconds = seconds;
    }

    public void clickedSettings(View view){
        Log.d(CLASS_NAME, "clickedSettings.");

        Intent settingsIntent = new Intent(this, SettingsActivity.class);

        startActivity(settingsIntent);
    }

    public void setTimeDisplay(){
        Log.d(CLASS_NAME, "setTimeDisplay");
        counter.setText(timer.display());
    }
}

这里是SettingsActivity类,其中保持振动选项:

package com.androiddevbook.onyourbike_chapter5.activities;

import com.androiddevbook.onyourbike.chapter5.helpers.Toaster;
import com.androiddevbook.onyourbike_chapter4.R;
import com.androiddevbook.onyourbike_chapter5.OnYourBike;
import com.androiddevbook.onyourbike_chapter5.model.Settings;
import android.support.v7.app.ActionBarActivity;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;

public class SettingsActivity extends ActionBarActivity {

    private CheckBox vibrate;
    private String CLASS_NAME = "dada";

    public SettingsActivity(){
        Log.d(CLASS_NAME, "SettingsActivity.class....");
        CLASS_NAME = getClass().getName();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
    private void setupActionBar() {

        if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
            ActionBar actionBar = getActionBar();
            actionBar.setDisplayHomeAsUpEnabled(true);
        }

    }

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

        vibrate = (CheckBox)
                findViewById(R.id.vibrate_checkbox);

        Settings settings = ((OnYourBike)getApplication()).getSettings();
        vibrate.setChecked(settings.isVibrateOn(this));

        setupActionBar();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.settings, 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.home) {
            goHome();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void goHome() {
        Log.d(CLASS_NAME, "gotoHome");

        Intent timer =
                new Intent(this, TimerActivity.class);
        timer.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        startActivity(timer);
    }

    public void onStop(){
        super.onStop();
        Settings settings = ((OnYourBike)getApplication()).getSettings();
        settings.setVibrate(this, vibrate.isChecked());
    }

    public void vibrateChanged(View view){
        Toaster toast = new Toaster(getApplicationContext());

        if(vibrate.isChecked())
            toast.make(R.string.vibrate_on);
        else
            toast.make(R.string.vibrate_off);
    }

    public void goBack(View view){
        finish();
    }
}

关于我的虚拟电话的说明:

CPU / ABI:ARM(armeabi-v7a)

目标:Android 5.0.1(API级别21)

扩展 ActionBarActivity ,您需要使用ActionBar

ActionBar actionBar = getSupportActionBar();

根据错误日志:

05-06 09:40:37.323: E/AndroidRuntime(945): Process: com.androiddevbook.onyourbike_chapter4, PID: 945
05-06 09:40:37.323: E/AndroidRuntime(945): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androiddevbook.onyourbike_chapter4/com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference

ActionBar actionBar = getActionBar(); line返回一个null对象。

原因:

  • ActionBarActivity子类FragmentActivity是一个支持组件,将代码更改为ActionBar actionBar = getSupportActionBar();
  • 你可能正在使用像...Light.NoActionBar这样的主题,所以这也是因为活动中没有ActionBar ,将主题更改为支持ActionBar的主题。

另外需要注意的是,这不是这个问题的原因,但是,不推荐使用ActionBarActivity ,从现在开始使用AppCompatActivity

您的错误日志说明了一切:

05-06 09:40:37.323: E/AndroidRuntime(945): Process: com.androiddevbook.onyourbike_chapter4, PID: 945
05-06 09:40:37.323: E/AndroidRuntime(945): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androiddevbook.onyourbike_chapter4/com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference

您正在调用null对象上的方法:

actionBar.setDisplayHomeAsUpEnabled(true);

因此,请确保执行空检查,或者您可能需要使用getSupportActionBar

像这样更改setupActionBar方法:

   @TargetApi(Build.VERSION_CODES.HONEYCOMB) 
        private void setupActionBar() {

            if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
               ActionBar actionBar = getSupportActionBar();
                actionBar.setDisplayHomeAsUpEnabled(true);
            }

        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM