尝试在空对象引用上调用虚拟方法“java.lang.String android.content.Context.getPackageName()”

Posted

技术标签:

【中文标题】尝试在空对象引用上调用虚拟方法“java.lang.String android.content.Context.getPackageName()”【英文标题】:Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a nullobjectreference 【发布时间】:2017-09-01 13:32:47 【问题描述】:

我正在尝试从我的 sqlite 数据库中获取一些数据-> 在 RecyclerView 中显示它-> 并点击一个我想开始新活动的项目。

但是当我点击其中一个时显示项目列表后,会弹出以下错误: java.lang.NullPointerException:

我的 mainActivityClass:

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.blue2dew.trakin.Item.item;
import com.example.blue2dew.trakin.MovieAdapter;


import java.util.ArrayList;




public class MainActivity extends AppCompatActivity 
    private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mtoggle;
private NavigationView navigationView;
private Toolbar toolbar;
private Movie_det movie_det;
Context context;

private RecyclerView recyclerView;
private DatabaseHelper databaseHelper;
 ArrayList<item> arrayList=new ArrayList<item>();
private Cursor cursor;
private MovieAdapter movieAdapter;


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


    mDrawerLayout=(DrawerLayout) findViewById(R.id.activity_main);
    navigationView=(NavigationView)findViewById(R.id.navigation_view);
    toolbar=(Toolbar)findViewById(R.id.nav_action);
    setSupportActionBar(toolbar);
    mtoggle=new ActionBarDrawerToggle(this,mDrawerLayout,R.string.open,R.string.close);

    recyclerView=(RecyclerView)findViewById(R.id.recycler_view);
    mDrawerLayout.addDrawerListener(mtoggle);
    mtoggle.syncState();

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() 
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) 
            item.setChecked(true);
            mDrawerLayout.closeDrawers();
            return false;
        
    );

    loadDatabase();




@Override
public boolean onOptionsItemSelected(MenuItem item)
    if(mtoggle.onOptionsItemSelected(item))
        return true;
    

    return super.onOptionsItemSelected(item);


public void loadDatabase()
    databaseHelper=new DatabaseHelper(MainActivity.this);

    try
        databaseHelper.checkAndCopyDatabase();
        databaseHelper.openDatabase();
    catch(SQLiteException e)
        e.printStackTrace();
    


    try 
        cursor = databaseHelper.QueryData("select * from movieDetails");
        if (cursor != null) 
            if (cursor.moveToFirst()) 
                do 
                    item itemv = new item();
                    itemv.setMovieName(cursor.getString(2));
                    itemv.setReleaseDate(cursor.getString(5));
                    itemv.setMovieImage(cursor.getBlob(1));

                    arrayList.add(itemv);


                 while (cursor.moveToNext());
            
        
    catch (SQLiteException e)
        e.printStackTrace();
    


    LinearLayoutManager linearLayoutManager=new LinearLayoutManager(getApplicationContext());
    movieAdapter=new MovieAdapter(MainActivity.this,context,arrayList);



    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setAdapter(movieAdapter);






我的适配器类:

package com.example.blue2dew.trakin;

import android.app.Activity;  
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;


import com.example.blue2dew.trakin.Item.item;


import java.util.Collections;
import java.util.List;



public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder>  
   Activity activity;
    List<item> items= Collections.emptyList();
    Context context;


public MovieAdapter(Activity activity,Context context, List<item> items)
    this.activity=activity;
    this.context=context;
    this.items=items;

@Override
public MovieViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_list_item,parent,false);

    MovieViewHolder movieViewHolder=new MovieViewHolder(view,context,items);
    return movieViewHolder;




public void onBindViewHolder(MovieViewHolder holder,final int position) 
    holder.movie_name.setText(items.get(position).getMovieName());
    holder.release_date.setText(items.get(position).getReleaseDate());
    holder.imageView.setImageBitmap(items.get(position).getMovieImage());






@Override
public int getItemCount() 
    return items.size();





public  class MovieViewHolder extends  RecyclerView.ViewHolder implements  View.OnClickListener


     ImageView md_image;
     TextView md_movie_name;
     TextView md_length1;
     TextView md_genre1;
     TextView md_release_date1;
     ImageView md_imdb_icon;
     TextView md_rating1;
     TextView md_director1;
     TextView md_synopsis1;

     TextView movie_name;
     TextView release_date;
     ImageView imageView;

    List<item> items=Collections.emptyList();
    Context context;

    public MovieViewHolder(View itemView,Context context,List<item> items ) 
        super(itemView);
        this.context=context;
        this.items=items;
        itemView.setOnClickListener(this);
        md_image = (ImageView) itemView.findViewById(R.id.md_image);
        md_director1 = (TextView) itemView.findViewById(R.id.md_director1);
        md_genre1 = (TextView) itemView.findViewById(R.id.md_genre1);
        md_movie_name = (TextView) itemView.findViewById(R.id.md_movie_name);
        md_length1 = (TextView) itemView.findViewById(R.id.md_length1);
        md_release_date1 = (TextView) itemView.findViewById(R.id.md_release_date1);
        md_rating1 = (TextView) itemView.findViewById(R.id.md_rating1);
        md_synopsis1 = (TextView)itemView.findViewById(R.id.md_synopsis1);
        md_imdb_icon = (ImageView) itemView.findViewById(R.id.md_imdb_icon);

        movie_name=(TextView) itemView.findViewById(R.id.movie_name);
        release_date=(TextView) itemView.findViewById(R.id.release_date);
        imageView=(ImageView) itemView.findViewById(R.id.imageView);


    


    @Override
    public void onClick(View v) 

        int position=getAdapterPosition();
        item item=this.items.get(position);
        Intent intent=new Intent (this.context,Main2Activity.class);
        this.context.startActivity(intent);

    
 


 

我的 databaseHelper 类: 包 com.example.blue2dew.trakin;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;



public class DatabaseHelper extends SQLiteOpenHelper 
 private static String DB_Name="movie.db";
private static String DB_Path;
private SQLiteDatabase mydatabase;
private final Context mycontext;




public DatabaseHelper(Context context) 
    super(context,DB_Name , null, 1);
    if(Build.VERSION.SDK_INT>=15)
        DB_Path=context.getApplicationInfo().dataDir+"/databases/";
    
    else
        DB_Path= Environment.getDataDirectory()+"/data/"+context.getPackageName()+"/databases/";
    
    this.mycontext=context;


@Override
public void onCreate(SQLiteDatabase db) 
    //using existing database  so creation not needed



@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    //the existing database need not be upgraded



public void checkAndCopyDatabase()
    boolean dbExist=checkDatabase();
    if(dbExist)
        Log.d("TAG","database already exists");
    
    else 
        this.getReadableDatabase();
    
    try 
        copyDatabase();
    
    catch (IOException e)
        e.printStackTrace();
        Log.d("TAG","Error Copy Database");
    


public boolean checkDatabase()
    SQLiteDatabase checkDB=null;
    try 
        String mypath = DB_Path + DB_Name;
        checkDB = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE);
    catch (SQLiteException e) 
        e.printStackTrace();

    
    if(checkDB!=null)
        checkDB.close();
    
    return checkDB!=null?true:false;



public void copyDatabase() throws IOException
    InputStream myInput=mycontext.getAssets().open(DB_Name);
    String outfilename=DB_Path+DB_Name;
    OutputStream myOutput=new FileOutputStream(outfilename);
    byte[] buffer=new byte[1024];
    int length;
    while ((length=myInput.read(buffer))>0)
        myOutput.write(buffer,0,length);
    
    myOutput.flush();
    myOutput.close();
    myInput.close();


public  void openDatabase()
    String myPath=DB_Path+DB_Name;
    mydatabase=SQLiteDatabase.openDatabase(myPath,null, SQLiteDatabase.OPEN_READWRITE);


public synchronized void close()
    if(mydatabase!=null)
        mydatabase.close();
    
    super.close();


public Cursor QueryData(String query)
    return  mydatabase.rawQuery(query,null);


错误:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.blue2dew.trakin, PID: 7430 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.(ComponentName.java:128)
at android.content.Intent.(Intent.java:4521) at com.example.blue2dew.trakin.MovieAdapter$MovieViewHolder.onClick(MovieAdapter.java:127)
at android.view.View.performClick(View.java:5209)
at android.view.View$PerformClick.run(View.java:21179)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5437)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

【问题讨论】:

可能不相关:当您可以从视图中获取上下文时,您的视图持有者和适配器中没有上下文和活动。 重新打开是因为这个 NPE 是由于缺乏对 Android 工作原理的理解造成的。 Suggested original question 过于笼统,在这种情况下没有帮助。 我的错!我刚开始学习android。谢谢你的回复!使用 View 获取上下文。 【参考方案1】:

你可以这样做,

    @Override
    public void onClick(View v) 
    int position=getAdapterPosition();
    item item=this.items.get(position);
    Intent intent=new Intent (v.getContext(),Main2Activity.class);
    v.getContext().startActivity(intent);

【讨论】:

谢谢,有帮助! 如果有帮助,请对此答案投票。编码快乐!

以上是关于尝试在空对象引用上调用虚拟方法“java.lang.String android.content.Context.getPackageName()”的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“ActionBar.setNavigationMode(int)”

NullPointerException:尝试在空对象引用上调用虚拟方法 AlertDialog.setTitle(java.lang.CharSequence) [重复]

(Kotlin,viewBinding)java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.lang.Thread.isAlive(

尝试在空对象引用上调用虚拟方法“java.lang.String android.content.Context.getPackageName()”

尝试在空对象引用上调用虚拟方法“java.lang.String android.content.Context.getPackageName()”

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“int android.view.View.getImportantForAccessibility()”