简体   繁体   English

尝试在 null object 参考上调用虚拟方法“android.content.Context.getResources()”

[英]Attempt to invoke virtual method 'android.content.Context.getResources()' on a null object reference

I try to use a fragment to open a database, however, when I click the button to begin searching, the program unexpectedly terminates and it show the error like this:我尝试使用片段打开数据库,但是,当我单击按钮开始搜索时,程序意外终止并显示如下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
     at android.widget.Toast.<init>(Toast.java:102)
     at android.widget.Toast.makeText(Toast.java:259)
     at com.example.nkwpy.myapplication.MainFragment.query(MainFragment.java:176)
     at com.example.nkwpy.myapplication.MainFragment.access$000(MainFragment.java:46)
     at com.example.nkwpy.myapplication.MainFragment$queryListener.onClick(MainFragment.java:161)
     at android.view.View.performClick(View.java:5207)
     at android.view.View$PerformClick.run(View.java:21177)
     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:5458)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)

MainFragment:主要片段:

package com.example.nkwpy.myapplication;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View.OnClickListener;
import android.widget.Toast;



/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link MainFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link MainFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class MainFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    MainActivity parent=(MainActivity) getActivity();
    SQLiteDatabase test;
    DBManager dbHelper;


    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private EditText N;
    private EditText Z;
    private EditText R_A;
    private Button queryBtn;

    private OnFragmentInteractionListener mListener;

    public MainFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment MainFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static MainFragment newInstance(String param1, String param2) {
        MainFragment fragment = new MainFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }


    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =inflater.inflate(R.layout.fragment_main, container, false);
        N=(EditText)view.findViewById(R.id.neuton);
        Z=(EditText)view.findViewById(R.id.proton);
        queryBtn = (Button)view.findViewById(R.id.query);
        queryBtn.setOnClickListener(new queryListener());
        R_A=(EditText)view.findViewById(R.id.result);


        dbHelper = new DBManager(getActivity());
        dbHelper.openDatabase();
        dbHelper.closeDatabase();
        return view;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p/>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    class queryListener implements OnClickListener{

        @Override
        public void onClick(View v) {
            //
            query();
            test.close();
        }
    }
    private void query() {

        try {
            String string1 = N.getText().toString();
            String string2 = Z.getText().toString();
            String sql = "select * from sly4 where N=" + string1 + " and Z=" + string2;
            Cursor cursor =test.rawQuery(sql, null);
            cursor.moveToFirst();
            String r = cursor.getString(cursor.getColumnIndex("value"));
            R_A.setText(r);
        } catch (Exception e) {
            Toast.makeText(parent, "Please check the number you entered", Toast.LENGTH_LONG).show();
        }
    }
}

class DBManager: class DBManager:

import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import android.content.Context;
 import android.database.sqlite.SQLiteDatabase;
 import android.os.Environment;
 import android.util.Log;

public class DBManager {
    private final int BUFFER_SIZE = 400000;
    public static final String DB_NAME = "main.db"; 
    public static final String PACKAGE_NAME = "com.example.nkwpy.myapplication";
    public static final String DB_PATH = "/data"
            + Environment.getDataDirectory().getAbsolutePath() + "/"
            + PACKAGE_NAME;

    private SQLiteDatabase database;
    private Context context;

    DBManager(Context context) {
        this.context = context;
    }

    public void openDatabase() {
        this.database = this.openDatabase(DB_PATH + "/" + DB_NAME);
    }

    private SQLiteDatabase openDatabase(String dbfile) {
        try {
            if (!(new File(dbfile).exists())) {
                InputStream is = this.context.getResources().openRawResource(R.raw.main);
                FileOutputStream fos = new FileOutputStream(dbfile);
                byte[] buffer = new byte[BUFFER_SIZE];
                int count = 0;
                while ((count = is.read(buffer)) > 0) {
                    fos.write(buffer, 0, count);
                }
                fos.close();
                is.close();
            }
            SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile,
                    null);
            return db;
        } catch (FileNotFoundException e) {
            Log.e("Database", "File not found");
            e.printStackTrace();
        } catch (IOException e) {
            Log.e("Database", "IO exception");
            e.printStackTrace();
        }
        return null;
    }
    public void closeDatabase() {
        this.database.close();
    }
}

By the way,I have used code about DBManager in MainAcitivity,and it succeeded.After I copy the code to the fragment like the one above,it failed.How should I do?顺便说一句,我在MainAcitivity中使用了关于DBManager的代码,它成功了。我将代码复制到上面的片段后,它失败了。我该怎么办?

You can't do MainActivity parent=(MainActivity) getActivity(); 你不能做MainActivity parent=(MainActivity) getActivity(); before onAttach() and after onDetach() . onAttach()之前和onDetach()

Since, you are doing at the time of fragment instantiation. 因为,您正在进行片段实例化。 The method getActivity will always return null. 方法getActivity将始终返回null。 Also as far as possible don't try to keep your Activity reference in your Fragment . 也尽可能不要尝试将您的Activity引用保留在Fragment This could cause memory leak if the reference is not nullified properly. 如果引用未正确无效,则可能导致内存泄漏。

Use getActivity() or getContext() wherever possible. 尽可能使用getActivity()getContext()

Change your Toast as below: 改变你的Toast如下:

Toast.makeText(getContext(), "Please check the number you entered", 
Toast.LENGTH_LONG).show(); 

or 要么

Toast.makeText(getActivity(), "Please check the number you entered", 
Toast.LENGTH_LONG).show();

Same error I went through! 我经历了同样的错误! It run well in MainActivity but not in my Fragment class. 它在MainActivity中运行良好,但在Fragment类中运行不佳。

I solved this problem by doing the following 2 things: 我通过以下两件事解决了这个问题:

1) In Fragment class, don't declare anything globally like we do in Activity class. 1)在Fragment类中,不要像在Activity类中那样全局声明任何内容。

For example: 例如:

public class HomeFragment extends Fragment {

// DON'T WRITE THIS HERE LIKE YOU DO IN ACTIVITY
String myArray[] = getResources().getStringArray();

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 ...
}

Instead, write anything inside 相反,在里面写任何东西

onCreateView() onCreateView()

method. 方法。

2) Use 2)使用

getActivity() getActivity()

method first and then 方法首先然后

getResource() method getResource()方法

  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

//WRITE LIKE THIS
 String myArray[] = getActivity().getResources().getStringArray(R.array.itemsList);

...
}

I had this issue in my android activity.The mistake was my Toast was not getting the context or I would prefer to call it reference of the activity. 我在我的android活动中遇到了这个问题。错误是我的Toast没有得到上下文,或者我更愿意称之为活动的参考。

Previous code:- 上一个代码: -

Toast.makeText(context, "Session Expire..!", Toast.LENGTH_SHORT).show();

Corrected Code:- 更正代码: -

Toast.makeText(activityname.this, "Session Expire..!", Toast.LENGTH_SHORT).show();

I too had this problem, took whole day to debug.我也有这个问题,花了一整天的时间调试。 mediaPlayer = MediaPlayer.create(this, R.raw.sound); mediaPlayer = MediaPlayer.create(这个,R.raw.sound); simply replace "this" keyword with the activity reference (unityActivity) from unity.. (if its a unity plugin) that how I solved it.只需将“this”关键字替换为来自unity..(如果它是一个统一插件)的活动参考(unityActivity),我是如何解决它的。

All you have to do in this case is;在这种情况下,您所要做的就是;

Create context;创建上下文; Assign it to the fragment context, then check for nonnull before using the created context.将其分配给片段上下文,然后在使用创建的上下文之前检查非空。

Like this...像这样...

    public class MyHome extends Fragment {
    
    **Context context;**
    
    public MyHome() {
        

    }


    public static MyHome newInstance() {
        return new MyHome();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        **this.context = getContext();**
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_my_home, container, false);

if(context !=null){
   Toast.makeText(context,"Hello homepage",Toast.LENGHT_LONG).show();
}

}
}

Declare a method like this:像这样声明一个方法:

private boolean checkContext(Context context) {
    if(context != null)
        return true;
    else
        return false;
}

Now if is activity execute this method onCreate() or onStart() like this:现在如果是活动执行这个方法 onCreate() 或 onStart() 像这样:

if(checkContext(getApplicationContext() or NameActivity.this))
{
   /// do stuff that hang from context
}

If is in fragment execute in onCreateView() or onStart like this:如果在片段中,在 onCreateView() 或 onStart 中执行,如下所示:

if(checkContext(getContext()))
{
   //dostuf that hang from context   
}

暂无
暂无

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

相关问题 例外:尝试在空对象引用上调用虚拟方法“android.content.res.Resources android.content.Context.getResources()” - Exception: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference 无法实例化活动:尝试调用虚拟方法 android.content.Context.getResources() - Unable to instantiate activity:Attempt to invoke virtual method android.content.Context.getResources() android.content.Context.getResources() 在空对象引用上 - android.content.Context.getResources() on a null object reference 尝试在空对象引用上调用虚拟方法&#39;android.content.Context android.content.Context.getApplicationContext()&#39; - Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference 尝试在 Android Studio 中的 null object 参考上调用虚拟方法 'android.content.Context.getApplicationInfo()' - Attempt to invoke virtual method 'android.content.Context.getApplicationInfo()' on a null object reference in Android Studio &#39;android.content.res.Resources android.content.Context.getResources()&#39; 在一个空对象引用上。 将字符串数组转换为语音 - 'android.content.res.Resources android.content.Context.getResources()' on a null object reference. Converting String array to speech 尝试在空对象引用上调用虚拟方法&#39;android.content.res.Resources $ Theme android.content.Context.getTheme()&#39; - Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference 蓝牙GATT尝试在空对象引用上调用虚方法&#39;void android.content.Context.sendBroadcast(android.content.Intent)&#39; - Bluetooth GATT Attempt to invoke virtual method 'void android.content.Context.sendBroadcast(android.content.Intent)' on a null object reference 问题:尝试在 null object 引用上调用虚拟方法“android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()” - Problem: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference 尝试在空对象引用上调用虚拟方法“java.lang.Object android.content.Context.getSystemService(java.lang.String)” - Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM