Java 尝试在空对象引用上调用虚拟方法“android.content.Context.getResources()”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39293294/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Attempt to invoke virtual method 'android.content.Context.getResources()' on a null object reference
提问by Perry_W
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.accesspackage 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();
}
}
}
0(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:
主片段:
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();
}
}
class DBManager:
类 DBManager:
Toast.makeText(getContext(), "Please check the number you entered",
Toast.LENGTH_LONG).show();
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的代码,成功了。我把代码复制到上面那个片段后,失败了,我该怎么办?
采纳答案by Kalpesh Patel
You can't do MainActivity parent=(MainActivity) getActivity();
before onAttach()
and after onDetach()
.
你不能在MainActivity parent=(MainActivity) getActivity();
之前onAttach()
和之后做onDetach()
。
Since, you are doing at the time of fragment instantiation. The method getActivity
will always return null. Also as far as possible don't try to keep your Activity
reference in your Fragment
. This could cause memory leak if the reference is not nullified properly.
因为,您是在片段实例化时进行的。该方法getActivity
将始终返回 null。也尽可能不要试图将您的Activity
引用保留在您的Fragment
. 如果未正确取消引用,这可能会导致内存泄漏。
Use getActivity()
or getContext()
wherever possible.
尽可能使用getActivity()
或getContext()
。
Change your Toast
as below:
改变你的Toast
如下:
Toast.makeText(getActivity(), "Please check the number you entered",
Toast.LENGTH_LONG).show();
or
或者
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) {
...
}
回答by Akshay Chopra
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 View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//WRITE LIKE THIS
String myArray[] = getActivity().getResources().getStringArray(R.array.itemsList);
...
}
Instead, write anything inside
相反,在里面写任何东西
onCreateView()
onCreateView()
method.
方法。
2) Use
2) 使用
getActivity()
获取活动()
method first and then
先方法再
getResource() method
getResource() 方法
Toast.makeText(context, "Session Expire..!", Toast.LENGTH_SHORT).show();
回答by Surbhi Kartpay
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(activityname.this, "Session Expire..!", Toast.LENGTH_SHORT).show();
Corrected Code:-
更正的代码:-
##代码##