Activity已泄露最初在此处注册的IntentReceiver。你是否错过了对unregisterReceiver()的调用?

时间:2012-10-19 01:51:42

标签: android service

我正在使用服务从该位置获取更新,它不是IntentService,但是日志显示活动已泄露最初在此处注册的IntentReceiver。你是否错过了对unregisterReceiver()的调用? 我不使用接收器,所以我不注册或取消注册。那么,这有什么关系呢?

我粘贴服务代码:

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class UpdateService2 extends Service {

    private LocationManager locManager;
    private LocationListener locListener;
    private Location loc;
    public static int UPDATE_TIME   = 30000;
    public static long MAX_TIME     = 600000;
    public static long waited = 0;
    boolean active = true;
    String TAG = "UpdateService2";
    Thread myThread;
    SharedPreferences prefs;
    SharedPreferences.Editor editor;


    @Override
    public IBinder onBind(Intent arg0) {
        Log.d(TAG, "onBind");
        return null;
    }

    public void onCreate() {
        Log.d(TAG, "onCreate");
        SharedPreferences prefs = getSharedPreferences(MyConstants.MY_PREFERENCES,Context.MODE_PRIVATE);
        editor = prefs.edit();
        startGettingLocation();

        Log.d("UpdateService","Thread - active:"+active+", maxTime: "+MAX_TIME);
        myThread = new Thread() {
            public void run(){
                Log.d("UpdateService","run");
                try {
                    waited = 0;
                    Log.d("UpdateService","Thread - active:"+active+", maxTime: "+MAX_TIME+", waited: "+waited);
                    while(active && (waited < MAX_TIME)) {
                        sleep(10000);
                        if(active) {
                            waited += 10000;
                            Log.d("UpdateService","Thread update: "+waited/1000+" seg");
                        }
                    }
                } catch(InterruptedException e) {
                    Log.d("UpdateService","Exception: "+e.toString());
                } finally {
                    interrupt();
                }
            }
        };
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        active = false;
    }

    @Override
    public void onStart(Intent intent, int startid) {
        myThread.start();
        Log.d(TAG, "onStart");
    }

    private void startGettingLocation(){
        try {
            locListener = new LocationListener() {
                public void onLocationChanged(Location location) {
                    updatePosition(location);
                    Log.d("UpdateService","Update location - Lat:"+location.getLatitude()+", Lon:"+location.getLongitude());
                }
                public void onProviderDisabled(String provider){
                }
                public void onProviderEnabled(String provider){
                }
                public void onStatusChanged(String provider, int status, Bundle extras){
                }
            };
            locManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
            locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, UPDATE_TIME, 0, locListener);
            loc = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if (loc != null) {
                updatePosition(loc);
            }
        } catch (Exception e){
            Log.d("UpdateService", e.toString());
        }
    }

    private void updatePosition(Location loc) {
        if(loc != null) {
            Double dLat = loc.getLatitude();
            Double dLon = loc.getLatitude();
            editor.putInt(MyConstants.PREFERENCES_LAT, dLat.intValue());
            editor.putInt(MyConstants.PREFERENCES_LON, dLon.intValue());
            editor.commit();
        }
    }

}

然后,来自活动onCreate的调用是这样的:

msgIntent = new Intent(this, UpdateService2.class);
startService(msgIntent);

来自onDestroy的调用是这样的:

stopService(msgIntent);

2 个答案:

答案 0 :(得分:1)

实际上,(我相信)你在requestLocationUpdates隐含地注册了一个接收者:

locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, UPDATE_TIME, 0, locListener);

您应该稍后致电removeUpdates

locManager.removeUpdates(locListener);

答案 1 :(得分:0)

这是“我的”解决方案(它真的来自这里:Alarms):

在清单上,我注册了我的广播接收器:

<!-- Register BroadcastReceiver -->  
<receiver android:name="com.example.MyReceiver"/>

这是接收器的实现:

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {  
        MyLocation myLocation = new MyLocation(context);
        myLocation.getLocation();
        SharedPreferences prefs = context.getSharedPreferences(MyConstants.MY_PREFERENCES,Context.MODE_PRIVATE);
        User.myLat =  (double) prefs.getInt(MyConstants.PREFERENCES_LAT, 0);
        User.myLon =  (double) prefs.getInt(MyConstants.PREFERENCES_LON, 0);
        User.isValidPosition = prefs.getBoolean(MyConstants.PREFERENCES_VALID, false);

        //TEST
        Toast.makeText(context, "Testing alarm onReceive - Lat:"+User.myLat/1E6
        +", Long:"+User.myLon/1E6+", isValid:"+User.isValidPosition, Toast.LENGTH_LONG).show();  
        Log.d("MyReceiver","Lat:"+User.myLat+", Long:"+User.myLon+", isValid:"+User.isValidPosition);
        }

    }

我使用的常量(在另一个类中):

public class MyConstants {
    public static String MY_PREFERENCES = "MyPreferences";
    public static String PREFERENCES_LAT = "lat";   
    public static String PREFERENCES_LON = "lon";   
    public static String PREFERENCES_VALID = "isValid";
    public static final int ALARM_REQUEST_CODE = 1;
}

MyLocation类,我从活动中调用的那个:

public class MyLocation {
private LocationManager locManager;
private LocationListener locListener;
private Location loc;
private SharedPreferences prefs;
private SharedPreferences.Editor editor;
private Context context;
private String TAG = "MyLocation";
private int UPDATE_TIME = 0;

public MyLocation(Context context){
    this.context = context;
    prefs = this.context.getSharedPreferences(MyConstants.MY_PREFERENCES,Context.MODE_PRIVATE);
    editor = prefs.edit();
}

public void getLocation(){
    //Register to get updates of the location
    locListener = new LocationListener() {
    public void onLocationChanged(Location location) {
    updatePosition(location);
    Log.d(TAG,"Update location - Lat:"+location.getLatitude()+", Lon:"+location.getLongitude());                                
}

public void onProviderDisabled(String provider){

}
public void onProviderEnabled(String provider){

}
public void onStatusChanged(String provider, int status, Bundle extras){

}
};
    startGettingLocation();
    locManager.removeUpdates(locListener);
}

private void startGettingLocation(){
    try {
        locManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, UPDATE_TIME, 0, locListener);
        loc = locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    if (loc != null) {
        updatePosition(loc);
    }
    } catch (Exception e){
        Log.d(TAG, e.toString());       
    }
}

private void updatePosition(Location loc) {
if(loc != null) {
    Double dLat = loc.getLatitude()*1E6;
    Double dLon = loc.getLongitude()*1E6;
    editor.putInt(MyConstants.PREFERENCES_LAT, dLat.intValue());
    editor.putInt(MyConstants.PREFERENCES_LON, dLon.intValue());
    editor.putBoolean(MyConstants.PREFERENCES_VALID, true);
    editor.commit();
} 
}

}

我将偏好和经度的引用放在首选项中,以便从应用程序轻松访问此数据。

最后,这是来自活动的电话,开始获取我的位置:

MyLocation myLocation;
myLocation = new MyLocation(this);
myLocation.getLocation();
scheduleUpdates(30);

在这种情况下,我只是在我做的那一刻之后30秒设置一个警报,但是这种行为很容易编程警报重复任何次数。 这是我用来建立警报的方法,即使应用程序关闭也会唤醒系统:

private void scheduleUpdates(int when){  
Log.d("CreateGroupFormActivity", "Alarm");
AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);  

Intent intent  = new Intent(this, MyReceiver.class);  
PendingIntent pIntent = PendingIntent.getBroadcast(this, MyConstants.ALARM_REQUEST_CODE, intent,  PendingIntent.FLAG_CANCEL_CURRENT);  
manager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + when * 1000, pIntent);       
} 
相关问题