[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();
}
}
答案 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);