2012-05-15 43 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