Attempting to call the virtual method "android.content.Context.getResources ()" in a reference to a null object

I am trying to use a snippet to open a database, however, when I click the button to start the search, the program terminates unexpectedly and it shows an error as follows:

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, eg 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(); } } } 

DBManager class:

 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 used the DBManager code in MainAcitivity, and it succeeded. After I copy the code into a snippet like above, it failed. How should I do it?

+6
source share
1 answer

You cannot execute MainActivity parent=(MainActivity) getActivity(); before onAttach() and after onDetach() .

So how do you do this while creating the fragment instance. The getActivity method getActivity always return null. Also, as much as possible, do not try to save the Activity link in your Fragment . This can lead to a memory leak if the link is not nullified.

Use getActivity() or getContext() where possible.

Change the Toast as shown below:

 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(); 
+14
source

All Articles