无法在另一个类的Async任务中从我的SQLiteOpenHelper类运行方法

时间:2014-03-11 11:24:04

标签: android android-asynctask nullpointerexception sqliteopenhelper

[edit]请允许我为代码的错综复杂和业余性质道歉。我过去三个月一直在努力开发Android(之前我花了三个月的时间熟悉基本的Java),而且我有活动,按钮和其他基本内容的概念,进入网络和AsyncTasks等很快就一直在挑战。感谢大家帮助我。

尝试在数据库中输入数据时,应用程序崩溃。我发布了下面的LogCat

这是扩展SQLiteOpenHelper的类:

package com.example.jsonbourne;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseTask extends SQLiteOpenHelper {

private static final int DB_VERSION = 1;
private static final String DB_NAME = "Examplebase";
private static final String TABLE_USER = "User";

public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_SURNAME = "surname";
public static final String COLUMN_AGE = "age";

public DatabaseTask(Context context) {
    super(context, DB_NAME, null, DB_VERSION);

}

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_USER_TABLE = "CREATE TABLE" + TABLE_USER + "("
            + COLUMN_ID + "INTEGER PRIMARY KEY" + COLUMN_NAME + " TEXT"
            + COLUMN_SURNAME + "TEXT" + COLUMN_AGE + "INTEGER" + ")";
    db.execSQL(CREATE_USER_TABLE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS" + TABLE_USER);
    onCreate(db);
}

public void addUser(User user) {
    ContentValues cvalues = new ContentValues();

    cvalues.put(COLUMN_NAME, user.getName());
    cvalues.put(COLUMN_SURNAME, user.getSurname());
    cvalues.put(COLUMN_AGE, user.getAge());

    SQLiteDatabase db = this.getWritableDatabase();

    db.insert(TABLE_USER, null, cvalues);
    db.close();

}

}

这是一个名为GetJson的活动AsyncTask的一部分:

                    for (int i = 0; i < jArray.length(); i++) {
                        JSONObject json = jArray.getJSONObject(i);
                        s = json.getString("name") + " "
                                + json.getString("surname") + " "
                                + ", Age:" + json.getString("age") + "\n";


                        JSONObject jsonExample = jArray.getJSONObject(0);
                        String name = jsonExample.getString("name");
                        String surname = jsonExample.getString("surname");
                        int age = jsonExample.getInt("age");



                        User userExample = new User(name, surname, age);



                        DatabaseTask dbtaskExample = new DatabaseTask(GetJson.this);
                        dbtaskExample.addUser(userExample);

一旦应用程序尝试在数据库中添加User实例,我就会强制关闭应用程序。根据我对该主题的研究,似乎我传递给DB类的上下文必定是问题所在。

LogCat如下:

03-11 03:10:41.347: W/dalvikvm(1396): threadid=11: thread exiting with uncaught  
exception (group=0xb1a33ba8)
03-11 03:10:41.367: E/AndroidRuntime(1396): FATAL EXCEPTION: AsyncTask #1
03-11 03:10:41.367: E/AndroidRuntime(1396): Process: com.example.jsonbourne, PID: 1396
03-11 03:10:41.367: E/AndroidRuntime(1396): java.lang.RuntimeException: An error occured  
while executing doInBackground()
03-11 03:10:41.367: E/AndroidRuntime(1396):     at   
android.os.AsyncTask$3.done(AsyncTask.java:300)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
java.util.concurrent.FutureTask.setException(FutureTask.java:222)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
java.util.concurrent.FutureTask.run(FutureTask.java:242)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at  
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at  
java.lang.Thread.run(Thread.java:841)
03-11 03:10:41.367: E/AndroidRuntime(1396): Caused by: java.lang.NullPointerException
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
com.example.jsonbourne.DatabaseTask.addUser(DatabaseTask.java:50)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
com.example.jsonbourne.GetJson$1.doInBackground(GetJson.java:121)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
com.example.jsonbourne.GetJson$1.doInBackground(GetJson.java:1)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
android.os.AsyncTask$2.call(AsyncTask.java:288)
03-11 03:10:41.367: E/AndroidRuntime(1396):     at 
java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-11 03:10:41.367: E/AndroidRuntime(1396):     ... 4 more

我试图理解为什么我得到NullPointerException但是在清单中声明了GetJson活动,据我所知,我不必在清单中声明DatabaseTask类它不是活动。

非常感谢任何帮助!

[edit]添加GetJson.java源代码和User.java源代码以及UserList源代码。我已从GetJson.java文件中删除了URL和IP代码,并将其替换为描述,但请放心,他们会将数据发回:

package com.example.jsonbourne;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

public class GetJson extends Activity {

    public ArrayList<String> sarray = new ArrayList<String>();

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getData();

    }

    public ArrayList<String> getData() {

        try {
            new AsyncTask<Void, Void, Void>() {

                @Override
                protected Void doInBackground(Void... params) {

                    try {

                        URL jsonURL = new URL(URL TO CONNECT TO);

                        HttpURLConnection connection = (HttpURLConnection) jsonURL
                                .openConnection();

                        connection.connect();

                        int responseCode = connection.getResponseCode();
                        String responseC = Integer.toString(responseCode);

                        Log.d("CONNECTION STATUS RESPONSE", responseC);

                        InputStream inputStream = connection.getInputStream();

                        Reader reader = new InputStreamReader(inputStream);

                        int contentLength = connection.getContentLength();

                        char[] charArray = new char[contentLength];

                        reader.read(charArray);

                        String responseData = new String(charArray);

                        Log.d("RESPONSE DATA", responseData);

                        // second stage

                        String result = "";
                        InputStream isr = null;

                        HttpClient httpClient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost(
                                JSON.PHP URL);
                        HttpResponse response = httpClient.execute(httppost);
                        HttpEntity entity = response.getEntity();
                        isr = entity.getContent();

                        BufferedReader readerz = new BufferedReader(
                                new InputStreamReader(isr, "iso-8859-1"));
                        StringBuilder sb = new StringBuilder();
                        String line = null;

                        while ((line = readerz.readLine()) != null) {
                            sb.append(line + "\n");
                        }

                        isr.close();
                        result = sb.toString();

                        String s = "";

                        JSONArray jArray = new JSONArray(result);

                        for (int i = 0; i < jArray.length(); i++) {
                            JSONObject json = jArray.getJSONObject(i);
                            s = json.getString("name") + " "
                                    + json.getString("surname") + " "
                                    + ", Age:" + json.getString("age") + "\n";


                            JSONObject jsonExample = jArray.getJSONObject(0);
                            String name = jsonExample.getString("name");
                            String surname = jsonExample.getString("surname");
                            int age = jsonExample.getInt("age");



                            User userExample = new User(name, surname, age);



                            DatabaseTask dbtaskExample = new DatabaseTask(GetJson.this);
                            dbtaskExample.getWritableDatabase();
                            dbtaskExample.addUser(userExample);

                            Log.d("USER", userExample.toString());

                            Log.d("INSIDE FOR LOOP", s + "\n");
                            sarray.add(s);
                        }

                        // sarray.add(s);
                        Log.d("YEAH", s);

                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        Log.d("NETWORK", "NETWORK ERROR");
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    return null;

                }

            }.execute();
        } catch (Exception e) {
        }

        return sarray;

    }
}

这是User.java代码:

package com.example.jsonbourne;

public class User {

    private String name;
    private String surname;
    private int age;

    public User(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;

    }

    public  String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public  int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return this.name + " " + this.surname + ", age " +  this.age ;
    }

}

最后,这是UserList.java类,它从GetJson获取数据并将它们调整为ListView:

package com.example.jsonbourne;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class UserList extends Activity {

    @Override
    public void onCreate(Bundle firebug) {
        super.onCreate(firebug);
        setContentView(R.layout.list_user);

        ListView lv = (ListView) findViewById(R.id.listv);



        GetJson gj = new GetJson();

        ArrayList<String> al = gj.getData();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
        }





        ArrayAdapter<String> adapter = new ArrayAdapter<String>(UserList.this,
                android.R.layout.simple_list_item_1, al);

        lv.setAdapter(adapter);
        Toast.makeText(this, "Synchronization complete", Toast.LENGTH_SHORT).show();
    }

}

3 个答案:

答案 0 :(得分:0)

致电时:

DatabaseTask dbtaskExample = new DatabaseTask(GetJson.this);
                        dbtaskExample.addUser(userExample);

您的查询会导致错误

String CREATE_USER_TABLE = "CREATE TABLE" + TABLE_USER + "("
            + COLUMN_ID + "INTEGER PRIMARY KEY" + COLUMN_NAME + " TEXT"
            + COLUMN_SURNAME + "TEXT" + COLUMN_AGE + "INTEGER" + ")";  

在下一个列名之前,您需要在表名,列名和数据类型以及逗号之间留出空格......所以您的查询应该是:

String CREATE_USER_TABLE = "CREATE TABLE " + TABLE_USER + "("
            + COLUMN_ID + " INTEGER PRIMARY KEY, " + COLUMN_NAME + " TEXT, "
            + COLUMN_SURNAME + " TEXT, " + COLUMN_AGE + " INTEGER" + ")";

答案 1 :(得分:0)

您需要在db对象上调用getWritableDatabase()

试试这个

DatabaseTask dbtaskExample = new DatabaseTask(GetJson.this);
dbtaskExample.getWritableDatabase() ;
dbtaskExample.addUser(userExample);

答案 2 :(得分:0)

public class GetJson extends Activity

new GetJson()

是有问题的组合。您无法使用new实例化活动。这样做会使它们变得无用,例如作为Context,当尝试将这个严重创建的活动用作Context时,这就是导致NPE的原因。

要解决此问题,请移除extends Activity并在任何需要的地方传递有效的Context

例如,

private Context mContext;

// constructor
public GetJson(Context c) {
  mContext = c;
}

// ...

  .. new DatabaseTask(mContext);

还将关键字和标识符之间缺少的空格添加到onCreate()中的SQL:

String CREATE_USER_TABLE = "CREATE TABLE " + TABLE_USER + "("
        + COLUMN_ID + " INTEGER PRIMARY KEY" + COLUMN_NAME + " TEXT"
        + COLUMN_SURNAME + " TEXT" + COLUMN_AGE + " INTEGER" + ")";

onUpgrade()

db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER);