数据插入SQLite后IntentService停止,插入第二次时给出NULLPOINTER EXCEPTION

时间:2012-10-14 16:11:55

标签: android sqlite service intentservice

我正在开发一个应用程序,当没有移动信号覆盖区域时,数据会保存到数据库中。当服务返回时,它将从数据库中获取所有数据并在服务器上上传。

现在我有两个问题。

  1. 当第一次数据插入数据库时​​,IntentService停止。(当网络服务恢复时,它也会在服务器上传数据,用于检查我使用计时器的网络连接。)我不想停止服务。
  2. 当我第二次启动服务时,它再次创建并提供Nullpointerexception。因为数据库中没有数据,所以它也提供了一些关于数据反转的其他错误。
  3. 我的代码有什么问题?我只是希望当用户启动服务时,它将一直运行到数据库中的最后一个数据,之后它将停止。我在intentservice中使用了线程,因为我的应用程序崩溃了。

    LogCat错误

    10-14 20:44:02.135: E/Service(10042): Service Created.. 
    10-14 20:44:02.505: E/Service Started(10042): Successful
    10-14 20:44:03.585: E/Service Network(10042): Network is offline
    10-14 20:44:08.656: E/Service Network(10042): Network is offline
    10-14 20:44:13.616: E/Service Network(10042): Network is offline
    10-14 20:44:18.646: E/Service Network(10042): Network is offline
    10-14 20:44:23.595: E/Service Network(10042): Network is offline
    10-14 20:44:29.526: E/Service Network(10042): Network is online
    10-14 20:44:31.256: E/Data Sent(10042): Response 200
    10-14 20:44:33.599: E/Service Network(10042): Network is online
    10-14 20:44:34.446: E/Data Sent(10042): Response 200
    10-14 20:44:38.646: E/Service Network(10042): Network is online
    10-14 20:44:40.616: E/Data Sent(10042): Response 200
    10-14 20:44:43.625: E/Service Network(10042): Network is offline
    10-14 20:44:48.595: E/Service Network(10042): Network is offline
    10-14 20:44:53.586: E/Service Network(10042): Network is offline
    10-14 20:45:20.486: E/Service(10042): Service Created.. 
    10-14 20:45:20.587: E/Service Started(10042): Successful
    10-14 20:45:20.627: E/Insertion(10042): java.lang.NullPointerException
    10-14 20:45:21.666: E/Service Network(10042): Network is offline
    10-14 20:45:23.616: E/Service Network(10042): Network is offline
    10-14 20:45:36.645: E/Service Network(10042): Network is offline
    10-14 20:45:38.585: E/Service Network(10042): Network is offline
    10-14 20:45:41.786: E/Service Network(10042): Network is online
    10-14 20:45:42.026: E/AndroidRuntime(10042): FATAL EXCEPTION: Timer-1
    10-14 20:45:42.026: E/AndroidRuntime(10042): java.lang.NullPointerException
    10-14 20:45:42.026: E/AndroidRuntime(10042):    at com.remote.synchronizer.haris.SQLiteAdapter.getAllContacts(SQLiteAdapter.java:93)
    10-14 20:45:42.026: E/AndroidRuntime(10042):    at com.remote.synchronizer.haris.OfflineDataService$1$1.run(OfflineDataService.java:80)
    10-14 20:45:42.026: E/AndroidRuntime(10042):    at java.util.Timer$TimerImpl.run(Timer.java:284)
    10-14 20:45:43.646: E/Service Network(10042): Network is online
    10-14 20:45:44.266: E/Data Sent(10042): Response 200
    

    SQLiteAdapter.java

    package com.remote.synchronizer.haris;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.http.NameValuePair;
    import org.apache.http.message.BasicNameValuePair;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    
    public class SQLiteAdapter extends SQLiteOpenHelper {
    
        public static final String DATABASE_NAME = "Product";
        public static final String TABLE_NAME = "Orders";
        public static final int DATABASE_VERSION = 1;
        public static final String KEY_ID = " _id";  //
        public static final String KEY_NAME = "name";
        public static final String KEY_SHOP = "shop";
        private static final String KEY_CITY = "city";
        private static final String KEY_DATE = "datee";
        private static final String KEY_ORDER = "orderr";
    
        private SQLiteDatabase sqLiteDatabase;
        private SQLiteAdapter sqLiteHelper=this;
    
        private static final String CREATE_TABLE =
                "CREATE TABLE " + TABLE_NAME + " ("
                        + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                        + KEY_NAME + " VARCHAR,"
                        + KEY_SHOP + " VARCHAR," + KEY_CITY + " VARCHAR, " + KEY_DATE + " VARCHAR, " + KEY_ORDER + " VARCHAR" +");";
    
    
        public SQLiteAdapter(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);  
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_TABLE);
            sqLiteDatabase=db;
        }
    
        /*public void close(){
            sqLiteHelper.close();
        }
         */
        public void insert(String name, String shop, String city, String datee, String orderr){
    
            try
            {
                ContentValues contentValues = new ContentValues();
                contentValues.put(KEY_NAME, name);
                contentValues.put(KEY_SHOP, shop);
                contentValues.put(KEY_CITY, city);
                contentValues.put(KEY_DATE, datee);
                contentValues.put(KEY_ORDER, orderr);
                sqLiteDatabase.insertOrThrow(TABLE_NAME, KEY_ID, contentValues);
                //sqLiteDatabase.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();
                Log.e("Insertion", e.toString());
            }
        }
    
        public void deleteAll(){
            sqLiteDatabase.delete(TABLE_NAME, null, null);
        }
    
        public void delete_byID(int id){
            sqLiteDatabase.delete(TABLE_NAME, KEY_ID+"="+id, null);
        }
    
        /*public Cursor queueAll(){
            String[] columns = new String[]{KEY_ID, KEY_NAME, KEY_SHOP, KEY_CITY,  KEY_DATE, KEY_ORDER};
            Cursor cursor = sqLiteDatabase.query(TABLE_NAME, columns, 
                    null, null, null, null, null);
    
            return cursor;
        }*/
    
        public List<NameValuePair> getAllContacts() {
            List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
    
            String selectQuery = "SELECT  * FROM " + TABLE_NAME;
            sqLiteHelper.getReadableDatabase();
            Cursor cursor = sqLiteDatabase.rawQuery(selectQuery, null);
    
            if(cursor.moveToFirst()){
                while(!cursor.isAfterLast())
                {
                    postParameters.add(new BasicNameValuePair("User", cursor.getString(cursor.getColumnIndex(KEY_NAME))));
                    postParameters.add(new BasicNameValuePair("ShopName", cursor.getString(cursor.getColumnIndex(KEY_SHOP))));
                    postParameters.add(new BasicNameValuePair("city", cursor.getString(cursor.getColumnIndex(KEY_CITY))));
                    postParameters.add(new BasicNameValuePair("OrderDate", cursor.getString(cursor.getColumnIndex(KEY_DATE))));
                    postParameters.add(new BasicNameValuePair("OrderDetail", cursor.getString(cursor.getColumnIndex(KEY_ORDER))));
                    cursor.moveToNext();
                }
    
            }
            //cursor.close();
            return postParameters;
        };
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(SQLiteAdapter.class.getName(),
                    "Upgrading database from version " + oldVersion + " to "
                            + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE);
            onCreate(db);
        }
    
    }
    

    OfflineDataService.java

    package com.remote.synchronizer.haris;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;
    import org.apache.http.NameValuePair;
    
    import android.app.IntentService;
    import android.content.Intent;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.util.Log;
    
    public class OfflineDataService extends IntentService {
    
        boolean wifi,edge;
        private Timer timer= new Timer();
        SQLiteDatabase db;
        String un,shop,city,date,order;
        private SQLiteAdapter mySQLiteAdapter;
        Cursor cursor;
    
        public OfflineDataService() {
            super("OfflineDataService");
        }
    
        @Override   
        public void onCreate() {
    
            super.onCreate();
    
            Log.e("Service", "Service Created.. ");
    
            mySQLiteAdapter = new SQLiteAdapter(this);
            mySQLiteAdapter.getWritableDatabase();
    
        }   
    
        @Override
        protected void onHandleIntent(final Intent intent) {
    
            final Handler threadHandler;  
            threadHandler = new Handler();
    
            new Thread(new Runnable(){
    
                @Override
                public void run() {
    
                    Bundle bundle=intent.getExtras();
                    un=bundle.getString("un");
                    shop=bundle.getString("shop");
                    city=bundle.getString("city");
                    date=bundle.getString("date");
                    order=bundle.getString("order");
    
                    Log.e("Service Started", "Successful");
    
                    //Inserting New Record
                    mySQLiteAdapter.insert(un,shop,city,date,order);
    
                    timer.scheduleAtFixedRate(new TimerTask(){
    
                        @Override
                        public void run() {
    
                            //Checking network connectivity
                            wifi=NetworkInfo.Wifi(OfflineDataService.this);
                            edge=NetworkInfo.EDGE(OfflineDataService.this);
    
                            if(wifi==true||edge==true)
                            {
                                Log.e("Service Network", "Network is online");
                                List<NameValuePair> contacts=new ArrayList<NameValuePair>();
    
                                contacts=mySQLiteAdapter.getAllContacts();
    
                                String url="http://10.0.2.2:3325/Product/Create?"; 
    
                                int response = 0;
    
                                try 
                                {
                                    response = CustomHttpClient.executeHttpPost(url, contacts);
    
                                    if(response==200)
                                    {
                                        Log.e("Data Sent", "Response 200");
                                    }
    
                                    else{
    
                                        Log.e("Service Data", "Faield to upload data" );
                                    }
    
                                }
                                catch (Exception e)
                                {
                                    Log.e("Data Sending", e.toString());
                                    e.printStackTrace();
                                }
                            }
                            else
                            {
                                Log.e("Service Network", "Network is offline");
                            }
                        }
    
                    }, 1000, 5000);
    
                }
    
            }).start();
        }
    
        /*@Override
        public void onDestroy() {
    
            super.onDestroy();
          //  mySQLiteAdapter.deleteAll();
            Log.e("Service Destroy", "Successful");
    
    
        }*/
    }
    

    我是否需要使用onStartCommand而不是onHandleIntent,还是需要使用服务而不是IntentService来控制它们?

1 个答案:

答案 0 :(得分:3)

这可能是问题,我看不到你在哪里保存可读数据库......改变这个:

sqLiteHelper.getReadableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery(selectQuery, null);

对此:

if(sqLiteDatabase == null || !sqLiteDatabase.isOpen()) {
    sqLiteDatabase = sqLiteHelper.getReadableDatabase();
}
Cursor cursor = sqLiteDatabase.rawQuery(selectQuery, null);

<强>加成

对于SQLiteOpenHelper,在创建 new 数据库时,onCreate() ,而不只是打开现有数据库...将构造函数更改为:

public SQLiteAdapter(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);  
    sqLiteDatabase = this.getWritableDatabase();
}

(并从sqLiteDatabase=db移除onCreate()

另外,我忘了这是一个两部分的问题。 IntentServices不能无限期运行,您应该使用服务(或切换到使用ContentProvider)。