Android SQLite转CSV按钮无响应,空指针异常问题求助
解决导出CSV时的NullPointerException问题
首先看你Logcat里的错误:Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase ir.arbn.www.mytestprogramsamanik.DatabaseHelper.getReadableDatabase()' on a null object reference,这个问题很明确——你在点击事件里使用的dbhelper对象根本没初始化,是个null值!
问题出在哪?
看你ResultActivity的按钮点击代码:
save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DatabaseHelper db = new DatabaseHelper(getApplicationContext()); // ... 中间代码 ... SQLiteDatabase myDb = dbhelper.getReadableDatabase(); // 这里dbhelper是null! // ... 后续代码 ... } });
你在这个方法里已经创建了db对象,但却去调用dbhelper.getReadableDatabase(),而dbhelper只是在类里声明了DatabaseHelper dbhelper;,从来没给它赋值,自然会抛出空指针异常。
解决方案
直接把dbhelper换成你已经初始化好的db对象就行,或者提前初始化dbhelper。这里推荐第一种,因为你已经在点击事件里创建了db实例,没必要再用另一个未初始化的对象。
另外还有两个小问题需要注意:
- 你导出CSV的时候只取了前3列数据(id、name、date),但你的数据库里还有track和answer两列,如果你需要导出全部数据,记得把这两列也加上。
- Android 6.0(API 23)及以上版本需要动态申请
WRITE_EXTERNAL_STORAGE权限,否则会无法创建文件,导出失败。
修改后的按钮点击代码示例
save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 检查权限(Android 6+需要) if (ContextCompat.checkSelfPermission(ResultActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(ResultActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100); return; } DatabaseHelper db = new DatabaseHelper(getApplicationContext()); File exportDir = new File(Environment.getExternalStorageDirectory(), ""); if (!exportDir.exists()) { exportDir.mkdirs(); } File file = new File(exportDir, "csvname.csv"); try { file.createNewFile(); CSVWriter csvWrite = new CSVWriter(new FileWriter(file)); SQLiteDatabase myDb = db.getReadableDatabase(); // 这里换成已初始化的db对象 Cursor curCSV = myDb.rawQuery("SELECT * FROM tbl_person", null); csvWrite.writeNext(curCSV.getColumnNames()); while (curCSV.moveToNext()) { // 导出全部5列数据 String arrStr[] = { curCSV.getString(0), curCSV.getString(1), curCSV.getString(2), curCSV.getString(3), curCSV.getString(4) }; csvWrite.writeNext(arrStr); } csvWrite.close(); curCSV.close(); // 提示用户导出成功 Toast.makeText(ResultActivity.this, "导出成功!", Toast.LENGTH_SHORT).show(); } catch (Exception sqlEx) { Log.e("ResultActivity", sqlEx.getMessage(), sqlEx); Toast.makeText(ResultActivity.this, "导出失败:" + sqlEx.getMessage(), Toast.LENGTH_SHORT).show(); } } });
补充权限处理
如果你的App目标SDK是23及以上,记得在AndroidManifest.xml里添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
同时处理权限申请的回调:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过,再次触发导出操作 save.performClick(); } else { Toast.makeText(this, "需要存储权限才能导出CSV", Toast.LENGTH_SHORT).show(); } } }
这样修改后,点击按钮应该就能正常导出CSV文件了。
内容的提问来源于stack exchange,提问作者A.R.B.N
相关产品推荐
相关产品推荐

