我是Android移动开发的新手。我创建了一个名为EmployeeList的数据库,它位于我的Assets文件夹中。我想从那里获取数据并在我的活动中以列表视图格式显示它。应用程序不断崩溃,我不知道为什么。谢谢你的帮助。
这是在线和我自己的示例代码的混合。
DatabaseHelper.java
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by ahadagali on 6/15/2017.
*/
public class DataBaseHelper extends SQLiteOpenHelper {
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.example.ahadagali.fivesdyag/databases/";
private static String DB_NAME = "EmployeeList";
private SQLiteDatabase myDataBase;
private final Context myContext;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
public Cursor fetchAll() {
Cursor myCursor;
myCursor = getReadableDatabase().rawQuery("select * from EmployeeList", null);
//myDataBase = this.getReadableDatabase();
if (myDataBase != null) {
myCursor = getReadableDatabase().rawQuery("select * from EmployeeList", null);
}
return myCursor;
}
}
activityThree.java
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import java.io.IOException;
public class activityThree extends AppCompatActivity {
Context context;
TextView name;
TextView phoneNum;
TextView jobPos;
TextView availability;
ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three);
name = (TextView)findViewById(R.id.tv_fullName);
phoneNum = (TextView)findViewById(R.id.tv_phoneNum);
jobPos = (TextView)findViewById(R.id.tv_jobPosition);
availability = (TextView) findViewById(R.id.tv_availability);
DataBaseHelper myDbHelper = new DataBaseHelper(context);
myDbHelper = new DataBaseHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
Cursor AllEmployees = myDbHelper.fetchAll();
AllEmployees.moveToFirst();
while (!AllEmployees.isAfterLast()){
AllEmployees.moveToNext();
}
String[] from = {AllEmployees.getString(1), AllEmployees.getString(2), AllEmployees.getString(3), AllEmployees.getString(4)};
int [] to = {R.id.tv_fullName, R.id.tv_phoneNum, R.id.tv_jobPosition, R.id.tv_availability};
ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_listview, AllEmployees, from, to, 0);
ListView myList = (ListView)findViewById(R.id.listView);
myList.setAdapter(adapter);
}
}
activity_three.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
item_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_fullName"
android:text="Name"
android:textColor="#4bb6d6"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_phoneNum"
android:text="734"
android:textColor="#b30000"
android:textSize="18dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_jobPosition"
android:text="Job Position"
android:textSize="16dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_availability"
android:text="Availability"
android:textSize="16dp"/>
</LinearLayout>
错误记录
06-15 07:09:00.579 27137-27165/com.example.ahadagali.fivesdyag I/OpenGLRenderer: Initialized EGL, version 1.4
06-15 07:09:00.579 27137-27165/com.example.ahadagali.fivesdyag D/OpenGLRenderer: Swap behavior 1
06-15 07:09:00.579 27137-27165/com.example.ahadagali.fivesdyag W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
06-15 07:09:00.579 27137-27165/com.example.ahadagali.fivesdyag D/OpenGLRenderer: Swap behavior 0
06-15 07:09:00.591 1296-1406/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:00.631 1296-1406/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:00.695 27137-27137/com.example.ahadagali.fivesdyag W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
06-15 07:09:00.782 1540-1598/system_process I/ActivityManager: Displayed com.example.ahadagali.fivesdyag/.MainActivity: +678ms
06-15 07:09:00.818 1296-1296/? W/SurfaceFlinger: couldn't log to binary event log: overflow.
06-15 07:09:00.969 1540-1598/system_process D/gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
06-15 07:09:01.903 1655-1655/com.android.inputmethod.latin I/LatinIME: Starting input. Cursor position = 0,0
06-15 07:09:01.909 1296-3089/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:01.933 1296-3089/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:01.973 1296-3089/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:03.531 1655-1655/com.android.inputmethod.latin I/LatinIME: Starting input. Cursor position = 0,0
06-15 07:09:03.536 27137-27137/com.example.ahadagali.fivesdyag W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
06-15 07:09:04.350 1540-2981/system_process I/ActivityManager: START u0 {cmp=com.example.ahadagali.fivesdyag/.activityTwo (has extras)} from uid 10073 on display 0
06-15 07:09:04.389 1296-1336/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:04.416 1296-1337/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:04.452 1296-1337/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
06-15 07:09:04.588 1540-1598/system_process I/ActivityManager: Displayed com.example.ahadagali.fivesdyag/.activityTwo: +232ms
06-15 07:09:04.591 27137-27137/com.example.ahadagali.fivesdyag W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
06-15 07:09:04.591 27137-27137/com.example.ahadagali.fivesdyag W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
06-15 07:09:06.247 1540-1554/system_process I/ActivityManager: START u0 {cmp=com.example.ahadagali.fivesdyag/.activityThree} from uid 10073 on display 0
06-15 07:09:06.280 27137-27137/com.example.ahadagali.fivesdyag D/AndroidRuntime: Shutting down VM
06-15 07:09:06.281 27137-27137/com.example.ahadagali.fivesdyag E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ahadagali.fivesdyag, PID: 27137
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ahadagali.fivesdyag/com.example.ahadagali.fivesdyag.activityThree}: android.database.CursorIndexOutOfBoundsException: Index 4 requested, with a size of 4
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: android.database.CursorIndexOutOfBoundsException: Index 4 requested, with a size of 4
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.ahadagali.fivesdyag.activityThree.onCreate(activityThree.java:68)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
06-15 07:09:06.282 1540-2982/system_process W/ActivityManager: Force finishing activity com.example.ahadagali.fivesdyag/.activityThree
06-15 07:09:06.286 1540-2982/system_process W/ActivityManager: Force finishing activity com.example.ahadagali.fivesdyag/.activityTwo
06-15 07:09:06.294 1302-1422/? D/AudioFlinger: mixer(0xa6403a40) throttle end: throttle time(43)
06-15 07:09:06.328 1296-1337/? D/gralloc_ranchu: gralloc_alloc: format 1 and usage 0x900 imply creation of host color buffer
答案 0 :(得分:0)
根本原因是:
引起:android.database.CursorIndexOutOfBoundsException:索引4 请求,大小为4
将索引请求更改为3(最大)。 索引为零。
可能在你的代码的这一行:
String[] from = {AllEmployees.getString(1), AllEmployees.getString(2), AllEmployees.getString(3), AllEmployees.getString(4)};
尝试0到3(输入1到4)。我猜你最多只有四列或者什么。
EDIT 尝试评论更改以下代码(注释我在下面评论的行) 我相信你正在迭代到数据的末尾,所以你的光标在你尝试阅读之前已经过了所有的数据。
AllEmployees.moveToFirst();
// while (!AllEmployees.isAfterLast()){
// AllEmployees.moveToNext();
// }
String[] from = {AllEmployees.getString(1), AllEmployees.getString(2), AllEmployees.getString(3), AllEmployees.getString(4)};
int [] to = {R.id.tv_fullName, R.id.tv_phoneNum, R.id.tv_jobPosition, R.id.tv_availability};
ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_listview, AllEmployees, from, to, 0);
ListView myList = (ListView)findViewById(R.id.listView);
myList.setAdapter(adapter);
编辑2
尝试用我的代码替换你的代码(以下3行):
ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_listview, AllEmployees, from, to, 0);
ListView myList = (ListView)findViewById(R.id.listView);
myList.setAdapter(adapter);
新代码
String[]values={"Android","iOS","Windows Phone","Other Stuff"};
ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, android.R.id.text1,values);
myList.setAdapter(adapter);
如果一切正常,请在工作代码(将添加数据库中的值)后尝试以下代码:
while (!AllEmployees.isAfterLast()){
AllEmployees.moveToNext();
adapter.add(AllEmployees.getString(0);
}
adapter.notifyDataSetChanged (); // updates the list in UI
仅在另一部分工作后添加此第二部分。 这不完全正确,但在此之后你应该能够解决它。