隨着Android程序功能模塊愈來愈多,模塊之間的交互也日漸日常,一個結構在開始就設計良好的系統,不會由於上述的緣由就出現大量的複製粘貼,若是出現大量的複製粘貼,那說明這個系統的結構設計是失敗的。之前在寫一個電子商務類聯網應用的時候,每一個Activity都有一個AsyncTask的異步線程去執行聯網下載數據,解析數據,每當新增一個功能模塊的時候就會出現大量的代碼複製粘貼。致使程序難以維護。因此對於這些須要處理大量耗時工做的應用,提出了一個由數據中心負責接收數據請求,處理好數據後將數據異步返回的機制。java
初步的設想是將數據中心放在Service中,而後經過binderService,每一個想要和Service通訊的Activity均可以鏈接到Service中。而後經過Handler發送數據請求給Service,Service根據請求,處理數據,而後經過BroadcastReceiver機制將數據返回給對此類數據感興趣的對象。android
一下是實現的關鍵代碼:app
package com.hxcy; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.IBinder; import android.os.Message; import android.support.v4.content.LocalBroadcastManager; import com.hxcy.model.Person; public class DataCenterService extends Service implements Callback { private Handler msgHandler; private MyBinder binder; public static final int GET_PERSON_DATA = 0X001; public static final int GET_COUNTRY_DATA = 0X002; public static final String GET_PERSON_ACTION = "com.hxcy.action.person"; public static final String GET_COUNTRY_ACTION = "com.hxcy.action.country"; private LocalBroadcastManager mLocalBroadcastManager; public class MyBinder extends Binder { public Handler getMessageHandler() { return msgHandler; } } @Override public IBinder onBind(Intent intent) { binder = new MyBinder(); msgHandler = new Handler(this); mLocalBroadcastManager = DataCenterApplication .getLocalBroadcastManager(); return binder; } @Override public boolean handleMessage(Message msg) { switch (msg.what) { case GET_PERSON_DATA: new PersonDataThrea().start(); return true; case GET_COUNTRY_DATA: return true; default: return false; } } class PersonDataThrea extends Thread { @Override public void run() { Intent intent = new Intent(GET_PERSON_ACTION); Bundle bundle = new Bundle(); Person[] persons = new Person[5]; for (int i = 0; i < 5; i++) { Person person = new Person(); person.setAge(i + 20); person.setName(i + " person"); person.setId(i + ":" + System.currentTimeMillis()); persons[i] = person; } bundle.putParcelableArray("persons", persons); intent.putExtras(bundle); mLocalBroadcastManager.sendBroadcast(intent); } } }
package com.hxcy; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.support.v4.content.LocalBroadcastManager; import com.hxcy.model.Person; import com.hxcy.util.LogUtil; public class DataCenterDemoActivity extends Activity { private LocalBroadcastManager mLocalBroadcastManager; private Handler msgHandler; private BroadcastReceiver personDataReceiver=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle bundle=intent.getExtras(); if(bundle!=null){ Person[] persons=(Person[]) bundle.getParcelableArray("persons"); for(int j=persons.length-1;j>=0;j--){ LogUtil.d(getApplicationContext(), persons[j]+""); } } } }; private ServiceConnection conn=new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } @Override public void onServiceConnected(ComponentName name, IBinder service) { msgHandler=((DataCenterService.MyBinder)service).getMessageHandler(); msgHandler.postDelayed(refreshPersonData, 3000); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mLocalBroadcastManager=DataCenterApplication.getLocalBroadcastManager(); mLocalBroadcastManager.registerReceiver(personDataReceiver, new IntentFilter(DataCenterService.GET_PERSON_ACTION)); bindService(new Intent(this,DataCenterService.class), conn, BIND_AUTO_CREATE); } Runnable refreshPersonData =new Runnable() { @Override public void run() { msgHandler.sendEmptyMessage(DataCenterService.GET_PERSON_DATA); msgHandler.postDelayed(this, 3000); } }; }
package com.hxcy;
import android.app.Application;
import android.support.v4.content.LocalBroadcastManager;
public class DataCenterApplication extends Application {
private static LocalBroadcastManager mLocalBroadcastManager;
@Override
public void onCreate() {
super.onCreate();
mLocalBroadcastManager=LocalBroadcastManager.getInstance(this);
}
public static LocalBroadcastManager getLocalBroadcastManager(){
return mLocalBroadcastManager;
}
}異步
Person類:ide
package com.hxcy.model; import android.os.Parcel; import android.os.Parcelable; public class Person implements Parcelable { private String name; private int age; private String id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public int describeContents() { return 0; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", id=" + id + "]"; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(id); dest.writeString(name); dest.writeInt(age); } public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() { @Override public Person createFromParcel(Parcel source) { // TODO Auto-generated method stub Person person=new Person(); person.setId(source.readString()); person.setName(source.readString()); person.setAge(source.readInt()); return person; } @Override public Person[] newArray(int size) { return new Person[size]; } }; }