2016-09-02 23 views
5

Tôi cố gắng sử dụng phân đoạn để mở cơ sở dữ liệu, tuy nhiên, khi tôi nhấp vào nút để bắt đầu tìm kiếm, chương trình sẽ kết thúc đột ngột và nó hiển thị lỗi như thế này:Cố gắng gọi phương thức ảo 'android.content.Context.getResources()' trên tham chiếu đối tượng rỗng

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

lớp 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(); 
    } 
} 

Bằng cách này, tôi đã sử dụng mã về DBManager trong MainAcitivity, và nó đã thành công. Sau khi tôi sao chép mã vào đoạn như trên, nó không thành công. Tôi nên làm gì?

+0

Hãy đề cập đến trong đó lớp và trong đó dòng bạn đang nhận được lỗi này để chúng tôi có thể đề nghị. –

+0

Đoạn của bạn chỉ chịu trách nhiệm đối với các hành động liên quan đến giao diện người dùng - đó là hành động không tốt để đặt quyền truy cập cơ sở dữ liệu tại đây. Thay vào đó, hãy thử gọi lại hoạt động để thực hiện công việc đó cho bạn. Đọc thêm tại đây: http://simpledeveloper.com/how-to-communicate-between-fragments-and-activities/ –

Trả lời

12

Bạn không thể làm MainActivity parent=(MainActivity) getActivity(); trước onAttach() và sau onDetach().

Vì bạn đang thực hiện tại thời điểm phân đoạn đoạn. Phương thức getActivity sẽ luôn trả về giá trị rỗng. Ngoài ra càng nhiều càng tốt, đừng cố gắng giữ tài liệu tham khảo Activity trong số Fragment của bạn. Điều này có thể gây rò rỉ bộ nhớ nếu tham chiếu không được vô hiệu hóa đúng cách.

Sử dụng getActivity() hoặc getContext() nếu có thể.

Thay đổi của bạn Toast như sau:

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

hoặc

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

cái nào hoạt động? sử dụng 'getActivity()' hoặc 'getContext()'? –

+0

cả hai đều không hoạt động với tôi –

+0

@GowthamanM Khi nào bạn gọi bất kỳ phương pháp nào ở trên? Bạn có gọi nó sau 'onDetach()' hoặc trước 'onAttach()'? –

Các vấn đề liên quan

 Các vấn đề liên quan