2012-05-15 42 views
1

我與unregisterReceiver()混淆。如果我們之前在代碼中註冊過,是否需要註銷接收方?我已經看到有時我們沒有註銷它,但仍然一切正常,但有時我們需要取消註冊,以擺脫運行時異常。Android - unregisterReceiver概念的詳細介紹?

請詳細解釋概念,如果可能的話用示例。我試過讀過幾本書,但沒有一本能解釋它,所以如果你知道某本書可以有很好的解釋,請告訴我。

我真的很感激你的努力。

謝謝。

回答

3

不,註銷接收器不是強制性的。如果您沒有取消註冊,接收機將繼續收到它從Android註冊的內容。當您不希望再收到更多廣播時,您應該取消註冊。

+5

此外,當您的活動被中止和接收器未註銷的Android會拋出異常。 – Guykun

-2

這個例子可以幫助..

更好的學習用一個例子

package com.commonsware.android.shaker; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.ScrollView; 
import android.widget.TextView; 

public class ShakerDemo extends Activity 
    implements Shaker.Callback { 
    private Shaker shaker=null; 
    private TextView transcript=null; 
    private ScrollView scroll=null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    transcript=(TextView)findViewById(R.id.transcript); 
    scroll=(ScrollView)findViewById(R.id.scroll); 

    shaker=new Shaker(this, 1.25d, 500, this); 
    } 

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

    shaker.close(); 
    } 

    public void shakingStarted() { 
    Log.d("ShakerDemo", "Shaking started!"); 
    transcript.setText(transcript.getText().toString()+"Shaking started\n"); 
    scroll.fullScroll(View.FOCUS_DOWN); 
    } 

    public void shakingStopped() { 
    Log.d("ShakerDemo", "Shaking stopped!"); 
    transcript.setText(transcript.getText().toString()+"Shaking stopped\n"); 
    scroll.fullScroll(View.FOCUS_DOWN); 
    } 
} 






package com.commonsware.android.shaker; 

import android.content.Context; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.os.SystemClock; 
import java.util.ArrayList; 
import java.util.List; 

public class Shaker { 
    private SensorManager mgr=null; 
    private long lastShakeTimestamp=0; 
    private double threshold=1.0d; 
    private long gap=0; 
    private Shaker.Callback cb=null; 

    public Shaker(Context ctxt, double threshold, long gap, 
        Shaker.Callback cb) { 
    this.threshold=threshold*threshold; 
    this.threshold=this.threshold 
        *SensorManager.GRAVITY_EARTH 
        *SensorManager.GRAVITY_EARTH; 
    this.gap=gap; 
    this.cb=cb; 

    mgr=(SensorManager)ctxt.getSystemService(Context.SENSOR_SERVICE); 
    mgr.registerListener(listener, 
          mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
          SensorManager.SENSOR_DELAY_UI); 
    } 

    public void close() { 
    mgr.unregisterListener(listener); 
    } 

    private void isShaking() { 
    long now=SystemClock.uptimeMillis(); 

    if (lastShakeTimestamp==0) { 
     lastShakeTimestamp=now; 

     if (cb!=null) { 
     cb.shakingStarted(); 
     } 
    } 
    else { 
     lastShakeTimestamp=now; 
    } 
    } 

    private void isNotShaking() { 
    long now=SystemClock.uptimeMillis(); 

    if (lastShakeTimestamp>0) { 
     if (now-lastShakeTimestamp>gap) { 
     lastShakeTimestamp=0; 

     if (cb!=null) { 
      cb.shakingStopped(); 
     } 
     } 
    } 
    } 

    public interface Callback { 
    void shakingStarted(); 
    void shakingStopped(); 
    } 

    private SensorEventListener listener=new SensorEventListener() { 
    public void onSensorChanged(SensorEvent e) { 
     if (e.sensor.getType()==Sensor.TYPE_ACCELEROMETER) { 
     double netForce=e.values[0]*e.values[0]; 

     netForce+=e.values[1]*e.values[1]; 
     netForce+=e.values[2]*e.values[2]; 

     if (threshold<netForce) { 
      isShaking(); 
     } 
     else { 
      isNotShaking(); 
     } 
     } 
    } 

    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
     // unused 
    } 
    }; 
} 
+0

我給了這個-1,因爲它甚至不使用廣播接收器。這是一個有用的例子嗎? – Justin