空对象引用上的ActionBar.setDisplayHomeAsUpEnabled

时间:2018-09-02 16:18:13

标签: java android nullpointerexception

在我的项目中,我收到此错误

  

java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.siddharth.cardnews / com.example.siddharth.cardnews.MainActivity}:java.lang.NullPointerException:尝试调用虚拟方法'void android.support .v7.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)'对空对象的引用

package com.example.siddharth.cardnews;

import android.annotation.SuppressLint;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.app.LoaderManager.LoaderCallbacks;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<NewsData>> {

/** Tag for log messages */
public static final String LOG_TAG = NewsLoader.class.getName();
private static String NEWS_REQUEST_URL ="https://newsapi.org/v2/top-headlines?country=in&apiKey=02d5a6c928c14944b23057e1054b68d9";
private static  final  int NEWS_LOADER_ID=1;
private  NewsAdapter mAdapter;
private TextView mEmptyStateTextView;
private DrawerLayout mDrawerLayout;


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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    ActionBar actionbar = getSupportActionBar();
    actionbar.setDisplayHomeAsUpEnabled(true);
    actionbar.setHomeAsUpIndicator(R.drawable.ic_menu);

    mDrawerLayout = findViewById(R.id.drawer_layout);

    NavigationView navigationView = findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    int country_url = menuItem.getItemId();
                    switch (country_url) {
                        case R.id.us_news:
                            NEWS_REQUEST_URL = "https://newsapi.org/v2/top-headlines?country=us&apiKey=02d5a6c928c14944b23057e1054b68d9";
                            break;
                        case R.id.au_news:
                            NEWS_REQUEST_URL = "https://newsapi.org/v2/top-headlines?country=au&apiKey=02d5a6c928c14944b23057e1054b68d9";
                            break;
                        case R.id.ca_news:
                            NEWS_REQUEST_URL = "https://newsapi.org/v2/top-headlines?country=ca&apiKey=02d5a6c928c14944b23057e1054b68d9";
                            break;
                    }

                    LoaderManager loaderManager = getLoaderManager();
                    loaderManager.restartLoader(NEWS_LOADER_ID, null, MainActivity.this);

                    mDrawerLayout.closeDrawers();

                    return true;
                }
            });

    ListView newsListView = (ListView) findViewById(R.id.list);

    // Create a new adapter that takes an empty list of earthquakes as input
    mAdapter = new NewsAdapter(this, new ArrayList<NewsData>());

    // Set the adapter on the {@link ListView}
    // so the list can be populated in the user interface
    newsListView.setAdapter(mAdapter);

    // Set an item click listener on the ListView, which sends an intent to a web browser
    // to open a website with more information about the selected earthquake.
    newsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            // Find the current earthquake that was clicked on
            NewsData currentNews = mAdapter.getItem(position);

            // Convert the String URL into a URI object (to pass into the Intent constructor)
            Uri newsUri = Uri.parse(currentNews.getmUrl());

            // Create a new intent to view the earthquake URI
            Intent websiteIntent = new Intent(Intent.ACTION_VIEW, newsUri);

            // Send the intent to launch a new activity
            startActivity(websiteIntent);
        }
    });

    mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
    newsListView.setEmptyView(mEmptyStateTextView);

    NewsAsyncTask task = new NewsAsyncTask();
    task.execute(NEWS_REQUEST_URL);

    ConnectivityManager connMgr = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

    if (networkInfo != null && networkInfo.isConnected()) {

        LoaderManager loaderManager = getLoaderManager();

        loaderManager.initLoader(NEWS_LOADER_ID, null, this);
    } else {
        View loadingIndicator = findViewById(R.id.loading_spinner);
        loadingIndicator.setVisibility(View.GONE);
        mEmptyStateTextView.setText(R.string.no_internet_connection);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public Loader onCreateLoader(int i, Bundle bundle) {
    return new NewsLoader(this,NEWS_REQUEST_URL);
}

@SuppressLint("WrongConstant")
@Override
public void onLoadFinished(Loader<List<NewsData>> loader, List<NewsData> news) {
    mAdapter.clear();
    if(news !=null && !news.isEmpty()){
        mAdapter.addAll(news);
    }
    mEmptyStateTextView.setText(R.string.no_news);

    ProgressBar spinner= (ProgressBar)findViewById(R.id.loading_spinner);
    spinner.setVisibility(View.GONE);

}

@Override
public void onLoaderReset(Loader<List<NewsData>> loader) {
    mAdapter.clear();

}

private class NewsAsyncTask extends AsyncTask<String, Void, List<NewsData>> {

    @Override
    protected List<NewsData> doInBackground(String... urls) {
        if (urls.length < 1 || urls[0] == null) {
            return null;
        }
        List<NewsData> result = QueryUtils.fetchNewsData(urls[0]);
        return result;

    }

    @Override
    protected void onPostExecute(List<NewsData> data) {
        mAdapter.clear();

        if (data != null && !data.isEmpty()) {
            mAdapter.addAll(data);
        }
    }
}

}

2 个答案:

答案 0 :(得分:0)

您可能在styles.xml中缺少windowActionBar项目

<style name="MyTheme" parent="Theme.AppCompat.Light.DarkActionBar">
   <item name="android:windowNoTitle">true</item>
   <item name="windowActionBar">true</item>
...
</style>

答案 1 :(得分:0)

错误消息告诉您actionbar在此行为空

actionbar.setDisplayHomeAsUpEnabled(true);

为避免这种情况,请在使用null之前先检查它是否为空,

ActionBar actionbar = getSupportActionBar();
if( actionbar != null ) {
    actionbar.setDisplayHomeAsUpEnabled(true);
    actionbar.setHomeAsUpIndicator(R.drawable.ic_menu);
}

您可能还想了解为什么返回空值的一些可能原因。例如,根据所使用的android版本,将windowNoTitle设置为true可能会导致没有操作栏,并导致该调用中的内容为空(请参阅here)。