以前對java中的觀察者模式只知道一點皮毛,在接觸android的過程中,逐漸認識到觀察者模式是如此的重要,android中許多地方都用到了觀察者模式例如ContentResolver操作,來總結一下android中觀察者模式的使用技巧
我所理解的觀察者模式是這樣子的::
以一個例子來說明: 在service中有一個int類型的數據i,我在service中啟動一個定時器去不斷更新這個值,當我在activity中啟動這個服務一次之後,每當i變化的時候我的activity要自動的同步更新這個值來顯示
1:觀察者主體 >> 接口
定義這個接口的目的就是處理數據的變化,當數據變化的時候就放到我們的參數中
一般我們定義該接口的時候將我們感興趣的數據作為方法中的參數【例如我們關心一個location那麼參數就為一個Location類型或是一個數據庫中總數的變化則參數就是一個int類型】
2: 觀察者操作者 >> 接口對象
//service中
public static InfoChangeObserver observer;
// 非service
public InfoChangeObserver observer;
public void setObserver(InfoChangeObserver o){
this.observer = o;
}
3:觀察者使用者 >> 給接口對象賦值
由於在service中我們不能直接new 一個service對象,因此我們一般將接口對象定義為一個static類型,在activity中通過MyService.observer = this來直接賦值[前提是你的activity實現了觀察者主體接口];除此之外,我們都會通過觀察者操作者提供的setCurrentObserver(InfoChangeObserver obsler)來賦值
接下來時源碼:
Interface 接口:
[java]
package com.example.performclickk;
public interface InfoChangeObserver
{
public int onDataChanged(int i);
}
Service
[java]
package com.example.performclickk;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service
{
// 監聽者對象
public static InfoChangeObserver observer;
@Override
public void onCreate()
{
// TODO Auto-generated method stub
Log.i( "ser", "MyService onCreate" );
super.onCreate();
}
// 監視的變量
int i = 0;
Timer timer;
TimerTask task;
@Override
public void onStart(Intent intent, int startId)
{
timer = new Timer();
task = new TimerTask()
{
@Override
public void run()
{
// TODO Auto-generated method stub
try
{
// 模擬長連接操作
Thread.sleep( 2000 );
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
// 監聽者監聽數據變化,把變化的數據放到onDataChanged(i)中去
if (observer != null)
{
observer.onDataChanged( i );
}
}
};
timer.schedule( task, 0, 2000 );
super.onStart( intent, startId );
}
@Override
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return null;
}
}
3:使用者 Activity
[java]
package com.example.performclickk;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.Deflater;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler.Callback;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.DialogInterface.OnClickListener;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements android.view.View.OnClickListener, InfoChangeObserver
{
Button button1, button2;
Context context;
// ceshi
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
context = this;
MyService.observer = this;
button1 = (Button) findViewById( R.id.button1 );
button2 = (Button) findViewById( R.id.button2 );
button1.setOnClickListener( this );
button2.setOnClickListener( this );
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.button1:
//數據會不斷變化
Log.i( "tag", i+"");
break;
case R.id.button2:
//啟動服務
Intent intent = new Intent( MainActivity.this, MyService.class );
intent.setAction( "com.example.performclickk.service" );
startService( intent );
break;
default:
break;
}
}
//監聽最新的數據
@Override
public void onDataChanged(int i)
{
return this.i = i;
}
}