我使用eclipse为Android应用程序进行数据库连接时遇到了麻烦
我有一个这方面的工作示例,但由于我已经调整了它,我无法打开数据库连接。
我有一个主要活动,在异步任务中打开“getData”
这会下载一个JOSN格式的文档,解析并传递给“writeSync”类
此类旨在打开数据库连接添加记录,然后关闭连接。
我在运行database.open方法时收到错误但无法捕获特定错误。
我已经检查过我没有传递Null值并且填充了Helper对象。
如果有人能发现我的问题,这是我的代码。
我还编写了一个包装类来在数据库打开时传递上下文
主要活动
package com.example.jsondb;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
public class MainActivity extends Activity {
public Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getContext contextrequest = new getContext();
AsyncTask<String, Void, String> JSONData;
//Get JSON Data as a string
//Update display#
//SyncDataProducts();
JSONData = new GetData().execute("null");
String WriteDB = "";
//pass JSONData to database to be written
//update display
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
GETDATA
package com.example.jsondb;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import android.os.AsyncTask;
import android.util.Log;
public class GetData extends AsyncTask<String, Void, String> {
public String getServerData(String strURL) {
InputStream is = null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("code","A"));
//get http data
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(strURL);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
String result = "";
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
//send data to database
AsyncTask<String, Void, String> WriteData;
WriteData = new WriteSync().execute(result);
return result;
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
return result;
}
@Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return getServerData("http://500kgiveaway.co.uk/android/products.php");
}
}
WRITESYNC
package com.example.jsondb;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
public class WriteSync extends AsyncTask<String, Void, String> {
private Context adapterContext;
public String WriteSyncData(String result) {
String httpResponce = "";
String returnstring = "";
httpResponce = result;
adapterContext = getContext.getContextNow();
DataSource datasource;
datasource = new DataSource(adapterContext);
datasource.open();
try{
JSONArray jArray = new JSONArray(httpResponce);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
datasource.createProduct(json_data.getString("stockref"), json_data.getString("title"), json_data.getString("price"));
//Get an output to the screen
returnstring += "\n\t" + jArray.getJSONObject(i);
}
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return returnstring;
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
return WriteSyncData(params[0]);
}
}
MYSQLHELPER
package com.example.jsondb;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MySQLiteHelper extends SQLiteOpenHelper{
//Product Table
public static final String TABLE_NAME = "products";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_STOCKREF = "stockref";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_PRICE = "price";
private static final String DATABASE_NAME = "Logma.db";
private static final int DATABASE_VERSION = 2;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_NAME
+ "(" + COLUMN_ID + " integer primary key autoincrement,"
+ COLUMN_STOCKREF + " text not null,"
+ COLUMN_TITLE + " text not null,"
+ COLUMN_PRICE + " text not null"
+ ");";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(MySQLiteHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
DATA SOURCE
package com.example.jsondb;
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
public class DataSource {
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allColumns_products = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_STOCKREF,MySQLiteHelper.COLUMN_TITLE,MySQLiteHelper.COLUMN_PRICE};
public DataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public String createProduct(String strStockRef, String strTitle, String strPrice) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_STOCKREF, strStockRef);
values.put(MySQLiteHelper.COLUMN_TITLE, strTitle);
values.put(MySQLiteHelper.COLUMN_PRICE, strPrice);
long insertId = database.insert(MySQLiteHelper.TABLE_NAME, null,
values);
return "Completed";
}
}
的getContext
package com.example.jsondb;
import android.content.Context;
public class getContext extends android.app.Application {
private static getContext instance;
public getContext() {
instance = this;
}
public static Context getContextNow() {
return instance;
}
}
这是我的堆栈跟踪
05-01 15:21:22.948: E/AndroidRuntime(24214): FATAL EXCEPTION: AsyncTask #2
05-01 15:21:22.948: E/AndroidRuntime(24214): java.lang.RuntimeException: An error occured while executing doInBackground()
05-01 15:21:22.948: E/AndroidRuntime(24214): at android.os.AsyncTask$3.done(AsyncTask.java:299)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
05-01 15:21:22.948: E/AndroidRuntime(24214): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.lang.Thread.run(Thread.java:856)
05-01 15:21:22.948: E/AndroidRuntime(24214): Caused by: java.lang.NullPointerException
05-01 15:21:22.948: E/AndroidRuntime(24214): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:236)
05-01 15:21:22.948: E/AndroidRuntime(24214): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
05-01 15:21:22.948: E/AndroidRuntime(24214): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
05-01 15:21:22.948: E/AndroidRuntime(24214): at com.example.jsondb.DataSource.open(DataSource.java:19)
05-01 15:21:22.948: E/AndroidRuntime(24214): at com.example.jsondb.WriteSync.WriteSyncData(WriteSync.java:24)
05-01 15:21:22.948: E/AndroidRuntime(24214): at com.example.jsondb.WriteSync.doInBackground(WriteSync.java:51)
05-01 15:21:22.948: E/AndroidRuntime(24214): at com.example.jsondb.WriteSync.doInBackground(WriteSync.java:1)
05-01 15:21:22.948: E/AndroidRuntime(24214): at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-01 15:21:22.948: E/AndroidRuntime(24214): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
05-01 15:21:22.948: E/AndroidRuntime(24214): ... 4 more
答案 0 :(得分:0)
我已经看了ContextWrapper
的源代码(抛出空指针异常的Android框架类),看来Context
正在为你的SQLiteOpenHelper
提供信息。 {1}}是null
。您请求Context
(使用“getContext”类 - 以大写字母开头)的方式对我来说似乎很尴尬。如果没有getContext()
方法可用,我通常会将“this” - 指针传递给我的Activity。在致电getReadableDatabase()
或getWritableDatabase()
之前,您不会发现此错误,因为SQLiteOpenHelper
在此之前不会使用给定的Context
。
除此之外:目前您的代码跟踪还会从后台线程调用AsyncTask.execute()
(具体来说,当您在execute()
内的WriteSync
上调用GetData.doInBackground()
时。文档,这是不允许的。你应该总是从主线程中调用AsyncTask.execute()
。我从经验中知道,尽管从大多数时间调用另一个线程的execute(),但它肯定不是正确的再次:这与你的问题无关(这只是你传递给SQLiteOpenHelper
的null - 上下文),但是当你在它的时候我会看一下。
答案 1 :(得分:0)
您应该使用与您的Async-Task相关的Activity,BordcastReceiver或Service的上下文。在您的情况下,使用MainActivity上下文:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
JSONData = new GetData(this.getContext()).execute("null");
public class GetData extends AsyncTask<String, Void, String> {
Context context = null
public GetData(Context context) {
this.context=context;