使用片段从数据库 SQLite 获取数据时出错

Posted

技术标签:

【中文标题】使用片段从数据库 SQLite 获取数据时出错【英文标题】:Error When Fetch data from database SQLite with fragment 【发布时间】:2018-02-24 03:12:27 【问题描述】:

这是我的片段活动,我在访问数据库时遇到错误我的代码是:

public class RainfallFragment extends Fragment 
public static final String KEY_DIVISION_ID="division_id";
public static final String KEY_DIVISION_NAME="division_name";
ListView listCollege;
ProgressBar proCollageList;
public Context context;
private mysqliteHelper dbHelper;
public RainfallFragment() 

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

    dbHelper = new MySQLiteHelper(getActivity());
   // dbHelper = new MySQLiteHelper(this);
    dbHelper.getReadableDatabase();



public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    // Inflate the layout for this fragment


    getActivity().setTitle("Rainfall Report");
    getActivity().setTitleColor(0000000);
    View v =inflater.inflate(R.layout.fragment_rainfall, container, false);
    context = v.getContext();

    v.setFocusableInTouchMode(true);
    v.requestFocus();
    v.setOnKeyListener(new View.OnKeyListener() 
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) 
            if (event.getAction() == KeyEvent.ACTION_DOWN) 
                if (keyCode == KeyEvent.KEYCODE_BACK) 
                    getActivity().finish();
                    Intent intent = new Intent(getActivity(), MainActivity.class);
                    startActivity(intent);

                    return true;
                
            
            return false;
        
    );

    //DISINI BATAS NYA//


    listCollege = (ListView)v.findViewById(R.id.listCollege);
    proCollageList = (ProgressBar)v.findViewById(R.id.proCollageList);

    new GetHttpResponse().execute();

    listCollege.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() 

        public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) 
            // On selecting single row to get detail information
            final String division_id = ((TextView) view.findViewById(R.id.adapter_text_id)).getText().toString();
            final String division_name = ((TextView) view.findViewById(R.id.adapter_text_estate)).getText().toString();

            AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
            b.setIcon(android.R.drawable.ic_dialog_alert);
            b.setMessage("Sure for choosing this estate");
            b.setPositiveButton("OK", new DialogInterface.OnClickListener() 

                public void onClick(DialogInterface dialog, int whichButton) 

                    Intent i = new Intent(getActivity(), RainfallReport.class);
                    i.putExtra(KEY_DIVISION_ID, division_id);
                    i.putExtra(KEY_DIVISION_NAME, division_name);
                    getActivity().startActivity(i);
                    dialog.dismiss();
                
            );

            b.setNegativeButton("Cancel", new DialogInterface.OnClickListener() 
                public void onClick(DialogInterface dialog, int whichButton) 
                
            );
            b.show();
        
    );
    return v;



private class GetHttpResponse extends AsyncTask<Void, Void, Void> 
    private Context context;
    String result;
    List<HashMap<String, String>> collegeList;



    @Override
    protected void onPreExecute()
    
        super.onPreExecute();
    

    @Override
    protected Void doInBackground(Void... arg0)
    
        List<Estate> estates = new LinkedList<Estate>();
        estates= dbHelper.getAllEstate();

        //Syntax for sort Listview Array by Id Ascending
        Collections.sort(estates, new Comparator<Estate>()
            @Override
            public int compare(Estate id1,Estate id2) 
                return id1.getDivision_id() - id2.getDivision_id();
            
        );

        // looping through All data

        for(Estate temp_vg: estates)
            temp_vg.getDivision_id();
            temp_vg.getDivision_name();

            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();
            // adding each child node to HashMap key => value
            map.put("division_id", String.valueOf(temp_vg.getDivision_id()));
            map.put("division_estate", temp_vg.getDivision_name());

            // adding HashList to ArrayList
            collegeList.add(map);
        

        return null;
    

    @Override
    protected void onPostExecute(Void result)

    
        proCollageList.setVisibility(View.GONE);
        listCollege.setVisibility(View.VISIBLE);
        if(collegeList != null)
        

            //adapter = new ListAdapterEstate(LihatDataEstate.this, map);
            ListAdapterEstate adapter = new ListAdapterEstate(collegeList, context);
            listCollege.setAdapter(adapter);

            //adapter=new LazyAdapter(Lihat_Data.this, dataList);
            //list.setAdapter(adapter);

        
    

MySQLiteHelper.java

  public class MySQLiteHelper extends SQLiteOpenHelper 



    private static final int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = "AARIDB.db";
    private SQLiteDatabase database;
    public MySQLiteHelper(Context context) 
        super(context, "/mnt/sdcard/AARIDB/DBAARI.db", null, DATABASE_VERSION);
        //super(context, DATABASE_NAME, null, DATABASE_VERSION);
    
          String RAINFALL_TABLE = "CREATE TABLE rainfall ( " +
                "division_id INTEGER PRIMARY KEY, " +
                "year_rainfall VARCHAR (5), "+
                "jan VARCHAR (10), "+
                "feb VARCHAR (10),"+
                "mar VARCHAR (10),"+
                "apr VARCHAR (10),"+
                "may VARCHAR (10),"+
                "jun VARCHAR (10),"+
                "jul VARCHAR (10),"+
                "aug VARCHAR (10),"+
                "sep VARCHAR (10),"+
                "oct VARCHAR (10),"+
                "nov VARCHAR (10),"+
                "dec VARCHAR (10),"+
                " FOREIGN KEY division_id REFERENCES "+ESTATE_TABLE+"division_id;";
        // create table
        db.execSQL(RAINFALL_TABLE);

    

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        // Drop older books table if existed

        db.execSQL("DROP TABLE IF EXISTS rainfall");

        // create fresh books table
        this.onCreate(db);
    

    //---------------------------------------------------------------------

    /**
     * CRUD operations (create "add", read "get", update, delete) book + get all  + delete all
     */


    private static final String TABLE_RAINFALL = "rainfall";
    // assesment Table Columns names
    public static final String KEY_DIVISION_ID_RAINFALL= "division_id";
    public static final String KEY_YEAR_RAINFALL= "year_rainfall";
    public static final String KEY_JAN_RAINFALL = "jan";
    public static final String KEY_FEB_RAINFALL = "feb";
    public static final String KEY_MAR_RAINFALL = "mar";
    public static final String KEY_APR_RAINFALL = "apr";
    public static final String KEY_MAY_RAINFALL = "may";
    public static final String KEY_JUN_RAINFALL = "jun";
    public static final String KEY_JUL_RAINFALL = "jul";
    public static final String KEY_AUG_RAINFALL = "aug";
    public static final String KEY_SEP_RAINFALL = "sep";
    public static final String KEY_OCT_RAINFALL = "oct";
    public static final String KEY_NOV_RAINFALL = "nov";
    public static final String KEY_DEC_RAINFALL = "dec";



    private static final String[] COLUMN_RAINFALL = 
            KEY_DIVISION_ID_RAINFALL,
            KEY_YEAR_RAINFALL,
            KEY_JAN_RAINFALL,
            KEY_FEB_RAINFALL ,
            KEY_MAR_RAINFALL ,
            KEY_APR_RAINFALL,
            KEY_MAY_RAINFALL,
            KEY_JUN_RAINFALL,
            KEY_JUL_RAINFALL,
            KEY_AUG_RAINFALL,
            KEY_SEP_RAINFALL,
            KEY_OCT_RAINFALL ,
            KEY_NOV_RAINFALL ,
            KEY_DEC_RAINFALL;


    public void addRAINFALL(Rainfall rainfall)
        Log.d("addRAINFALL", rainfall.toString());
        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();
        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        values.put(KEY_DIVISION_ID_RAINFALL, rainfall.getDivision_id()); // get est
        values.put(KEY_YEAR_RAINFALL, rainfall.getYear_rainfall());
        values.put(KEY_JAN_RAINFALL , rainfall.getJan());
        values.put(KEY_FEB_RAINFALL, rainfall.getFeb());
        values.put(KEY_MAR_RAINFALL, rainfall.getMar()); // get estate name
        values.put(KEY_APR_RAINFALL, rainfall.getApr());
        values.put(KEY_MAY_RAINFALL, rainfall.getMay());
        values.put(KEY_JUN_RAINFALL, rainfall.getJun());
        values.put(KEY_JUL_RAINFALL, rainfall.getJul()); // get estate name
        values.put(KEY_AUG_RAINFALL, rainfall.getAug());
        values.put(KEY_SEP_RAINFALL, rainfall.getSep());
        values.put(KEY_OCT_RAINFALL , rainfall.getOct()); // get estate name
        values.put(KEY_NOV_RAINFALL,rainfall.getNov());
        values.put(KEY_DEC_RAINFALL, rainfall.getDec());
        // 3. insert
        db.insert(TABLE_RAINFALL, // table
                null, //nullColumnHack
                values); // key/value -> keys = column names/ values = column values
        // 4. close
        db.close();
    


    public List<Rainfall> getAllRainfall() 
        List<Rainfall> rainfall = new LinkedList<Rainfall>();
        // 1. build the query
        String query = "SELECT  * FROM " + TABLE_RAINFALL+" ORDER BY "+KEY_DIVISION_ID_RAINFALL;
        // 2. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(query, null);
        // 3. go over each row, build book and add it to list
        Rainfall rainfall1 = null;
        if (cursor.moveToFirst()) 
            do 
                rainfall1 = new Rainfall();
                rainfall1.setDivision_id(Integer.parseInt(cursor.getString(0)));
                rainfall1.setYear_rainfall(cursor.getString(1));
                rainfall1.setJan(cursor.getString(2));
                rainfall1.setFeb(cursor.getString(3));
                rainfall1.setMar(cursor.getString(4));
                rainfall1.setApr(cursor.getString(5));
                rainfall1.setMay(cursor.getString(6));
                rainfall1.setJun(cursor.getString(7));
                rainfall1.setJul(cursor.getString(8));
                rainfall1.setAug(cursor.getString(9));
                rainfall1.setSep(cursor.getString(10));
                rainfall1.setOct(cursor.getString(11));
                rainfall1.setNov(cursor.getString(12));
                rainfall1.setDec(cursor.getString(13));
                // Add vgm
                rainfall.add(rainfall1);
             while (cursor.moveToNext());
        
        return rainfall;
    




    public Cursor getAllDataRainfall() 
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor mCursor = db.query("SELECT year_rainfall, jan, feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec FROM rainfall",
                new String[] KEY_YEAR_RAINFALL,KEY_JAN_RAINFALL,KEY_FEB_RAINFALL,KEY_MAR_RAINFALL,KEY_APR_RAINFALL,KEY_MAY_RAINFALL,
                KEY_JUN_RAINFALL,KEY_JUL_RAINFALL,KEY_AUG_RAINFALL,KEY_SEP_RAINFALL,KEY_OCT_RAINFALL,KEY_NOV_RAINFALL,KEY_DEC_RAINFALL,
                null, null, null, null, null);
        if (mCursor != null) 
            mCursor.moveToFirst();
        
        db.close();
        return mCursor;
    

我只需要在片段中访问数据库。任何人都会帮助我,我将不胜感激。错误的日志猫如下。

注意! at com.test.myapplication.RainfallFragment.onCreate(RainfallFragment.java:40)指的是dbHelper.getReadableDatabase();

09-14 22:20:16.387 1247-1247/com.test.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                      Process: com.test.myapplication, PID: 1247
                                                                      java.lang.NullPointerException
                                                                          at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
                                                                          at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
                                                                          at com.test.myapplication.RainfallFragment.onCreate(RainfallFragment.java:40)
                                                                          at android.support.v4.app.Fragment.performCreate(Fragment.java:2068)
                                                                          at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1055)
                                                                          at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
                                                                          at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
                                                                          at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
                                                                          at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:536)
                                                                          at android.os.Handler.handleCallback(Handler.java:733)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:136)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5001)
                                                                          at java.lang.reflect.Method.invokeNative(Native Method)
                                                                          at java.lang.reflect.Method.invoke(Method.java:515)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                                                                          at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

您的问题暗示该问题与从您的片段访问数据库有关。你确认是这样的吗?尝试从其他地方(活动、应用程序类...)访问数据库,看看是否遇到相同的错误。 请编辑您的问题以清楚地表明这指的是哪一行 at com.test.myapplication.RainfallFragment.onCreate(RainfallFragment.java:40)。您的 TABLE CREATE SQL 有错误,它应该等于 CREATE TABLE rainfall (division_id INTEGER PRIMARY KEY, year_rainfall VARCHAR (5), jan VARCHAR (10), feb VARCHAR (10), mar VARCHAR (10), apr VARCHAR (10), may VARCHAR (10), jun VARCHAR (10), jul VARCHAR (10), aug VARCHAR (10), sep VARCHAR (10), oct VARCHAR (10), nov VARCHAR (10), dec VARCHAR (10), FOREIGN KEY (division_id) REFERENCES ESTATE_TABLE progress(division_id)); ... 那是围绕 division_id 的括号(两者)和最后一个右括号。修复后,您应该 a) 卸载应用程序,b) 清除应用程序的数据或 c) 增加版本号,然后重新运行应用程序。不知道这是否是原因。 错误是指dbHelper.getReadableDatabase(); 堆栈跟踪是因为将 null 或其他无效的上下文传递给 SQLiteOpenHelper。您发布的代码甚至无法编译,因此不会导致该堆栈跟踪。 【参考方案1】:

我无法设置您的 MySQLiteHelper 的 onCreate。你需要放

String RAINFALL_TABLE = "CREATE TABLE rainfall ( " +
            "division_id INTEGER PRIMARY KEY, " +
            "year_rainfall VARCHAR (5), "+
            "jan VARCHAR (10), "+
            "feb VARCHAR (10),"+
            "mar VARCHAR (10),"+
            "apr VARCHAR (10),"+
            "may VARCHAR (10),"+
            "jun VARCHAR (10),"+
            "jul VARCHAR (10),"+
            "aug VARCHAR (10),"+
            "sep VARCHAR (10),"+
            "oct VARCHAR (10),"+
            "nov VARCHAR (10),"+
            "dec VARCHAR (10),"+
            " FOREIGN KEY division_id REFERENCES "+ESTATE_TABLE+"division_id;";
    // create table
    db.execSQL(RAINFALL_TABLE);

在你的 MySQLiteHelper 的 onCreate 中创建这样的表

@Override
public void onCreate(SQLiteDatabase db) 
    String RAINFALL_TABLE = "CREATE TABLE rainfall ( " +
            "division_id INTEGER PRIMARY KEY, " +
            "year_rainfall VARCHAR (5), "+
            "jan VARCHAR (10), "+
            "feb VARCHAR (10),"+
            "mar VARCHAR (10),"+
            "apr VARCHAR (10),"+
            "may VARCHAR (10),"+
            "jun VARCHAR (10),"+
            "jul VARCHAR (10),"+
            "aug VARCHAR (10),"+
            "sep VARCHAR (10),"+
            "oct VARCHAR (10),"+
            "nov VARCHAR (10),"+
            "dec VARCHAR (10),"+
            " FOREIGN KEY division_id REFERENCES "+ESTATE_TABLE+"division_id;";
    // create table
    db.execSQL(RAINFALL_TABLE);         


【讨论】:

【参考方案2】:

我已经解决了这个问题.. 只需更改我在 RainfallFragment 中的代码

来自:

List<HashMap<String, String>> collegeList;

到:

ArrayList<HashMap<String, String>> collegeList = new ArrayList<HashMap<String, String>>();

进入我的 Asynctask RainfallFargment 。

【讨论】:

【参考方案3】:

MySQLiteHelper 一样更改它:

public class MySQLiteHelper 
    private SQLiteDatabase db;
    private Context context;
    private DBHelper dbHelper;

    public MySQLiteHelper(Context context) 
            dbHelper = new DBHelper(context);

        

    public MySQLiteHelper open() throws SQLException 
            db = dbHelper.getWritableDatabase();
            return this;
        

    public void close() 
            dbHelper.close();
           

    public class DBHelper extends SQLiteOpenHelper 

            public DBHelper(Context context) 
                super(context, "/mnt/sdcard/AARIDB/DBAARI.db", null, 1);
            

            @Override
            public void onCreate(SQLiteDatabase db) 
                db.execSQL(RAINFALL_TABLE);//create tables
            

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
                db.execSQL("DROP TABLE IF EXISTS rainfall"); //drop tables if exists and than create or alter
                this.onCreate(db);
            
        

来自其他activity的电话:

MySQLiteHelper db = new MySQLiteHelper(MainActivity.this);

【讨论】:

不兼容的类型。必需:android.database.sqlite.SQLiteDatabase 找到:com.test.myapplication.MySQLiteHelper :((仍然错误) 无限递归不是答案 对不起,我不明白@laalto 我也不了解您的解决方案@AmitVaghela 你建议让构造函数创建一个新对象,然后再次调用相同的构造函数。

以上是关于使用片段从数据库 SQLite 获取数据时出错的主要内容,如果未能解决你的问题,请参考以下文章

当我从用户获取数据并将其保存到 SQLite 数据库中时,我应该怎么做才能使列表视图在片段中工作

从 2 个不同片段的 sqlite 中的 2 个表中获取信息

需要帮助从 SQLite 数据库中获取数据

如何使用光标和循环显示来自 sqlite 的片段的 recyclerview

当sqlite android片段中的数据更改或删除时如何刷新recyclerview?

如何在片段内的 recylerview 列表中显示 SQLite 数据库数据?