使用SQL Helper Android Eclipse打开连接时出现SQL异常错误

时间:2013-05-01 11:12:59

标签: java android sqlite

我使用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

2 个答案:

答案 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;