获取光标时出现问题!
我有一个数据库(SQLite),其中包含一个带有 GPS 数据的表格:经度和纬度!我确信该数据库存在并包含数据,因为我已经成功获得了整个数据上的光标并显示了它在屏幕上。
现在,我的应用程序应该比在数据库中写入并显示数据大一点。我应该通过套接字将数据发送到另一个应用程序。
为此,我创建了另一个线程,它连接到另一个应用程序并打开数据库并读取数据并将其发送到另一个应用程序。
public class screen1 extends Activity {
public void onCreate(Bundle savedInstanceState) {
Thread cThread=new Thread(new ClientThread());
cThread.start();
db=new DBAdapter(this);
}
这是我的 ClientThread 类;
public class ClientThread implements Runnable{
private PrintWriter out=null;
public void run()
{
try
{
InetAddress serverAddr=InetAddress.getByName(serverIpAddress);
socket=new Socket(serverAddr,ClientPort);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
Log.d(" ","Clientul is connected");
}
catch(UnknownHostException e){
System.err.println("Don't know about host");
}
catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to host");
}
try{
db.createDatabase();
db.openDataBase();
Cursor c=db.getAllData();
Log.d(" ","before the cursor");
if(c.moveToFirst())
{
do{
Log.d(" ","after the cursor");
longitude=c.getString(1);
latitude=c.getString(2);
Log.d(longitude,latitude);
}while(c.moveToNext());
}
socket.close();
}
catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
现在我面临的问题是这个 - 我试图显示我的经度和纬度,但我的程序永远无法进入这个循环:
if(c.moveToFirst())
{
do{
Log.d(" ","after the cursor");
longitude=c.getString(1);
latitude=c.getString(2);
Log.d(longitude,latitude);
}while(c.moveToNext());
}
我是如何测试的? ....=r我使用过如下消息: Log.d(" ","before the Cursor")
-before that loop 以及 Log.d(" ","after光标”)
。
现在第一个总是显示,但第二个永远不会显示。
有人知道问题是什么吗?因为如果我尝试将光标移到该线程之外的数据上,一切都会正常工作 - 数据会显示......而且我正在做同样的事情!
另一件事是,如果我使用语句 if(!c.moveToFirst())
程序将进入循环并显示第二条消息,但我在 logcat 中收到此错误:
04-19 07:51:31.450: ERROR/AndroidRuntime(611): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at test.android.screen1$ClientThread.run(screen1.java:96)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at java.lang.Thread.run(Thread.java:1096)
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
..What is that ......所以在那个光标处绝对是我唯一的问题,但是什么呢?
预先感谢您有用的回复!我来这里是为了了解更多详细信息!
更新:
公共类 DBAdapter 扩展 SQLiteOpenHelper {
public static final String DATABASE_PATH = "data/data/test.android/database";
public static final String DATABASE_NAME = "GPSdata";
public static final String DATABASE_TABLE_1= "route";
public static final String DATABASE_TABLE_2= "car1_data";
public static final String KEY_ROWID_1= "_id";
public static final String KEY_NAMEOFCAR="name_of_car";
public static final String KEY_ROWID_2 = "_id";
public static final String KEY_LONGITUDE= "longitude";
public static final String KEY_LATITUDE = "latitude";
public static final String KEY_ROUTE= "route";
public SQLiteDatabase db;
private final Context myContext;
public DBAdapter(Context context) {
super(context, DATABASE_NAME, null, 1);
this.myContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
// check if exists and copy database from resource
createDB();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("SqlHelper", "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
onCreate(db);
}
public void createDatabase() {
createDB();
}
private void createDB() {
boolean dbExist = DBExists();
if (!dbExist) {
copyDBFromResource();
}
}
private boolean DBExists() {
SQLiteDatabase db = null;
try {
String databasePath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
db.setVersion(1);
} catch (SQLiteException e) {
Log.e("SqlHelper", "database not found");
}
if (db != null) {
db.close();
}
return db != null ? true : false;
}
private void copyDBFromResource() {
InputStream inputStream = null;
OutputStream outStream = null;
String dbFilePath = DATABASE_PATH + DATABASE_NAME;
try {
inputStream = myContext.getAssets().open(DATABASE_NAME);
outStream = new FileOutputStream(dbFilePath);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
outStream.flush();
outStream.close();
inputStream.close();
} catch (IOException e) {
throw new Error("Problem copying database from resource file.");
}
}
public void openDataBase() throws SQLException {
String myPath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if (db != null)
db.close();
super.close();
}
public long insertData1(String name_of_car) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAMEOFCAR, name_of_car);
return db.insert(DATABASE_TABLE_1, null, initialValues);
}
public long insertData2(int longitude, int latitude, String route) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_LONGITUDE, longitude);
initialValues.put(KEY_LATITUDE, latitude);
initialValues.put(KEY_ROUTE, route);
return db.insert(DATABASE_TABLE_2, null, initialValues);
}
public Cursor getAllData()
{
return db.query(DATABASE_TABLE_2, new String[] {KEY_ROWID_2,KEY_LONGITUDE,KEY_LATITUDE},null,null,null,null,null);
}
public void clearSelections() {
ContentValues values = new ContentValues();
values.put(" selected", 0);
this.db.update(DBAdapter.DATABASE_TABLE_2, values, null, null);
}
}
I have a database(SQLite) which contains a tabel with GPS data:longitude and latitude!I'm sure that the database exists and contains the data because I've succed to obtain a cursor all over the data and I've displayed it on the screen.
Now,my app should be a little much bigger than writing in a database and display the data.I should send the data through a socket to another app.
For that I've created another thread which connects to the other app and opens the database and reads the data and sends it to the other app.
public class screen1 extends Activity {
public void onCreate(Bundle savedInstanceState) {
Thread cThread=new Thread(new ClientThread());
cThread.start();
db=new DBAdapter(this);
}
And here is my ClientThread class;
public class ClientThread implements Runnable{
private PrintWriter out=null;
public void run()
{
try
{
InetAddress serverAddr=InetAddress.getByName(serverIpAddress);
socket=new Socket(serverAddr,ClientPort);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
Log.d(" ","Clientul is connected");
}
catch(UnknownHostException e){
System.err.println("Don't know about host");
}
catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to host");
}
try{
db.createDatabase();
db.openDataBase();
Cursor c=db.getAllData();
Log.d(" ","before the cursor");
if(c.moveToFirst())
{
do{
Log.d(" ","after the cursor");
longitude=c.getString(1);
latitude=c.getString(2);
Log.d(longitude,latitude);
}while(c.moveToNext());
}
socket.close();
}
catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
Now the problem I'm facing is this one-I'm trying to get my longitude and latitude displayed but my program never reaches to get into this loop:
if(c.moveToFirst())
{
do{
Log.d(" ","after the cursor");
longitude=c.getString(1);
latitude=c.getString(2);
Log.d(longitude,latitude);
}while(c.moveToNext());
}
How I've tested that? ....=rI've used messages like: Log.d(" ","before the cursor")
-before that loop and also Log.d(" ","after the cursor")
.
Now the first one is always displayed but the second one never is.
Does someone knows what is the problem?Because if I try to get a cursor over the data outside this thread everything works just fine-the data is displayed....and I'm doing the same thing!
Another thing is that if I use the statement if(!c.moveToFirst())
the program enters the loop and the second message is displayed buut I get this error in the logcat:
04-19 07:51:31.450: ERROR/AndroidRuntime(611): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at test.android.screen1$ClientThread.run(screen1.java:96)
04-19 07:51:31.450: ERROR/AndroidRuntime(611): at java.lang.Thread.run(Thread.java:1096)
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
..What is that?...........So at that cursor is my definitly uniquee problem,but what?
Thank u in advance for your usefull reply!!!I'm here for further details!!!
UPDATE:
public class DBAdapter extends SQLiteOpenHelper {
public static final String DATABASE_PATH = "data/data/test.android/database";
public static final String DATABASE_NAME = "GPSdata";
public static final String DATABASE_TABLE_1= "route";
public static final String DATABASE_TABLE_2= "car1_data";
public static final String KEY_ROWID_1= "_id";
public static final String KEY_NAMEOFCAR="name_of_car";
public static final String KEY_ROWID_2 = "_id";
public static final String KEY_LONGITUDE= "longitude";
public static final String KEY_LATITUDE = "latitude";
public static final String KEY_ROUTE= "route";
public SQLiteDatabase db;
private final Context myContext;
public DBAdapter(Context context) {
super(context, DATABASE_NAME, null, 1);
this.myContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
// check if exists and copy database from resource
createDB();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("SqlHelper", "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
onCreate(db);
}
public void createDatabase() {
createDB();
}
private void createDB() {
boolean dbExist = DBExists();
if (!dbExist) {
copyDBFromResource();
}
}
private boolean DBExists() {
SQLiteDatabase db = null;
try {
String databasePath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
db.setVersion(1);
} catch (SQLiteException e) {
Log.e("SqlHelper", "database not found");
}
if (db != null) {
db.close();
}
return db != null ? true : false;
}
private void copyDBFromResource() {
InputStream inputStream = null;
OutputStream outStream = null;
String dbFilePath = DATABASE_PATH + DATABASE_NAME;
try {
inputStream = myContext.getAssets().open(DATABASE_NAME);
outStream = new FileOutputStream(dbFilePath);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
outStream.flush();
outStream.close();
inputStream.close();
} catch (IOException e) {
throw new Error("Problem copying database from resource file.");
}
}
public void openDataBase() throws SQLException {
String myPath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if (db != null)
db.close();
super.close();
}
public long insertData1(String name_of_car) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAMEOFCAR, name_of_car);
return db.insert(DATABASE_TABLE_1, null, initialValues);
}
public long insertData2(int longitude, int latitude, String route) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_LONGITUDE, longitude);
initialValues.put(KEY_LATITUDE, latitude);
initialValues.put(KEY_ROUTE, route);
return db.insert(DATABASE_TABLE_2, null, initialValues);
}
public Cursor getAllData()
{
return db.query(DATABASE_TABLE_2, new String[] {KEY_ROWID_2,KEY_LONGITUDE,KEY_LATITUDE},null,null,null,null,null);
}
public void clearSelections() {
ContentValues values = new ContentValues();
values.put(" selected", 0);
this.db.update(DBAdapter.DATABASE_TABLE_2, values, null, null);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果 c.moveToFirst() 确实返回 false,则您的光标似乎为空。您确定您的查询正确并且数据库已打开等吗?
也许发布一些代码。
此致,
直到
If c.moveToFirst() does return false your cursor seems to be empty. Are you sure that your query was correct and the database is opened etc.
Maybe post some of that code.
Best Regards,
Till