2010-08-08 22 views
7

मैं अपने एंड्रॉइड अनुप्रयोगों में स्थानीय डेटाबेस पहुंच को संभालने का सबसे अच्छा तरीका जानने का प्रयास कर रहा हूं। मैं प्रत्येक गतिविधि में डेटाबेस कनेक्शन ऑब्जेक्ट बना रहा था लेकिन यह चीजों को करने के लिए वास्तव में अक्षम तरीके जैसा लगता है। कुछ शोध करना मैंने this discussion पर ठोकर खाई। सेवा का उपयोग करना चीजों को करने का एक शानदार तरीका है, लेकिन मुझे इसे काम करने में परेशानी हो रही है।एंड्रॉइड ऐप में सभी गतिविधियों के बीच डेटाबेस कनेक्शन साझा करने के लिए एक सेवा बनाना?

सेवा:

public class DBservice extends Service { 
    private final static String TAG = "net.iamcorbin.frolfcard"; 
    public DBconn db; 

    private DBbinder mDatabaseBinder = new DBbinder(); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.d(TAG,"DBservice : onCreate"); 
     mDatabaseBinder.mDatabaseService = this; 
     this.db = new DBconn(getApplicationContext()); 
     this.db.open(); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     Log.d(TAG,"DBservice : onBind"); 
     return mDatabaseBinder; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startID) { 
     Log.d(TAG,"DBservice : onStartCommand"); 
     return Service.START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.d(TAG,"DBservice : onDestroy"); 
     mDatabaseBinder.mDatabaseService = null; 
     this.db.close(); 
    } 
} 

बांधने की मशीन:

public class DBbinder extends Binder { 

    public DBservice mDatabaseService; 

    public DBconn getDB() { 
     return mDatabaseService.db; 
    } 
} 

सेवा कनेक्शन:

public class DBserviceConn implements ServiceConnection { 
    private final static String TAG = "net.iamcorbin.frolfcard"; 

    DBbinder mBinder; 

    public DBserviceConn(DBbinder binder) { 
     Log.d(TAG,"DBseviceConn : Constructor"); 
     this.mBinder = binder; 
    } 

    public void onServiceConnected(ComponentName className, IBinder binder) { 
     Log.d(TAG,"DBseviceConn : OnServiceConnected"); 
     this.mBinder = (DBbinder) binder; 
    } 

    public void onServiceDisconnected(ComponentName arg0) { 
     Log.d(TAG,"DBseviceConn : OnServiceDisconnected"); 
    } 

}

तक पहुँचने:

यहाँ मैं क्या है
private DBbinder dbBinder; 
private DBserviceConn dbServiceConn; 

//In onCreate() for Activity that wants to access database 
//Setup DB Service Connection and Binder 
this.dbServiceConn = new DBserviceConn(this.dbBinder); 
final Intent i_DBservice = new Intent(PickGame.this, DBservice.class); 
//bind DB Service 
this.bindService(i_DBservice, this.dbServiceConn, BIND_AUTO_CREATE); 

यह किसी भी त्रुटि फेंक बिना निष्पादित करता है लेकिन जब मैं कोशिश करते हैं और साथ डेटाबेस का उपयोग करें:

this.dbServiceConn.mBinder.mDatabaseService.db.queryPlayers(); 

यह एक NullPointerException फेंकता है। चर्चा (उपरोक्त लिंक) पढ़ने से मुझे लगता है कि ऐसा इसलिए है क्योंकि डेटाबेस अभी तक खुला नहीं है क्योंकि मैं bindService के बाद तुरंत पूछताछ कर रहा हूं। हालांकि सूची सूची को पॉप्युलेट करने के लिए मुझे डेटाबेस का उपयोग करने की आवश्यकता है।

तो सवाल
1. क्या मैं सेवा, बांधने वाला और सेवा कनेक्शन ठीक से बना रहा हूं?
2. यदि हां, तो सेवा शुरू होने, बाध्य होने और डेटाबेस खोले जाने के बाद मैं सूची दृश्य को पॉप्युलेट करने के लिए कॉलबैक बनाने के बारे में कैसे जा सकता हूं?

+1

आप ऑब्जेक्ट ऑब्जेक्ट में संदर्भ क्यों नहीं रखते हैं, जो कि सभी गतिविधियों के लिए उपलब्ध है। – Pentium10

+0

मैं वास्तव में इस सुबह के बारे में सोच रहा था। क्या मैं अभी भी ऊपर की तरह सेवा बनाउंगा और बस इसे शुरू कर दूंगा और इसे अपने आवेदन ऑब्जेक्ट में बांध दूंगा? –

+0

एक स्थिर चर वाला सिंगलटन क्लास भी एक विकल्प है। – st0le

उत्तर

9

वाह, यह बहुत आसान है। मैंने सेवा हटा दी और एप्लिकेशन ऑब्जेक्ट में डेटाबेस कनेक्शन को संभाला।

आवेदन:

public class App extends Application { 
    public DBconn db; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     this.db = new DBconn(getApplicationContext()); 
     this.db.open(); 
    } 

    @Override 
    public void onTerminate() { 
     this.db.close(); 
     super.onTerminate(); 
    } 
} 

पहुंच:

this.app = ((App)getApplicationContext()); 

this.lv_players_c = this.app.db.queryPlayers(); 

धन्यवाद Pentium10। मैं अभी भी जानना चाहूंगा कि कनेक्शन को संभालने का यह सबसे प्रभावी तरीका है या नहीं। क्या एप्लिकेशन लाइफसाइक्ल की अवधि के लिए डेटाबेस कनेक्शन खोलना ठीक है? या जब भी मुझे किसी गतिविधि में इसका उपयोग करने की आवश्यकता होती है तो डेटाबेस को खोलना और बंद करना बेहतर होगा?

इस विधि का उपयोग करने के किसी भी अन्य सुझाव या पुष्टि महान होगी।

+0

आधिकारिक दस्तावेज़ बताते हैं कि आप अपने आवेदन पर भरोसा नहीं कर सकते हैं।इसका मतलब यह है कि सभी लेखन को जीवन विधि में नवीनतम बिंदु के रूप में ऑन पॉज़ विधि में किया जाना चाहिए। डेटाबेस में खुले कनेक्शन के साथ हर समय कोई अन्य समस्या नहीं है जो मैं सोच सकता हूं। – Janusz

+0

मैं उसी समाधान के साथ गया और ऐसा लगता है कि यह बहुत अच्छा काम कर रहा है। – taer

+2

'परमाणु प्रक्रिया वातावरण में उपयोग के लिए' पर आधारित नहीं है (http://developer.android.com/reference/android/app/Application.html#onTerminate%28%29) केवल? – yozh

0

आपको आलसी ListView भरना होगा, आप DBserviceConn को गतिविधि में निहित निजी के रूप में घोषित कर सकते हैं।

public void onServiceConnected(ComponentName className, IBinder binder) { 
    Log.d(TAG,"DBseviceConn : OnServiceConnected"); 
    this.mBinder = (DBbinder) binder; 
    //this.mBinder.mDatabaseService.db.queryPlayers(); // No NullPointerException here 
    mBaseAdapter.notifyDataSetChanged(); //Notify ListView BaseAdapter that data chaged 
} 
संबंधित मुद्दे