Java asynctask(Android)中3个回调WeakReference中的1个变为null

Java asynctask(Android)中3个回调WeakReference中的1个变为null,java,android,android-asynctask,null,weak-references,Java,Android,Android Asynctask,Null,Weak References,我和我的申请学校项目简介 嗨 我对android非常陌生,对于一些学校项目,我正在构建一个应用程序,用户可以在其中配置区域以接收来自的警报。应用程序还需要能够接收应用程序用户当前位置的警报 应用程序从xml提要获取信息,并按配置的区域对数据进行排序。工作流程为1。获取已配置区域中的警报。2.当gps警报启用时,应用程序需要获取位置,当知道位置时,需要再次执行第一步,但这次包括gps区域。(我以后需要优化此过程) (问题如下) 我的应用和问题介绍 我正在应用程序中使用asynctask下载一些x

我和我的申请学校项目简介

我对android非常陌生,对于一些学校项目,我正在构建一个应用程序,用户可以在其中配置区域以接收来自的警报。应用程序还需要能够接收应用程序用户当前位置的警报

应用程序从xml提要获取信息,并按配置的区域对数据进行排序。工作流程为1。获取已配置区域中的警报。2.当gps警报启用时,应用程序需要获取位置,当知道位置时,需要再次执行第一步,但这次包括gps区域。(我以后需要优化此过程)

(问题如下)


我的应用和问题介绍

我正在应用程序中使用asynctask下载一些xml提要。当asynctask准备就绪时,我需要调用3个位置来处理结果

1类将结果保存在本地数据库中(alertmanager) 2个片段(在选项卡视图中)需要显示结果(1个在映射中,1个在列表视图中)

现在,我使用
weakreferences
为异步任务提供回调“引用”。在
onPostExecute()
中,我使用
weakreference.get().updateMethod(结果)用于更新类/片段

alertmanager(需要接收更新的类)还以调用asynctask以获取gps位置的相同方法调用gps管理器。当我注释掉(在我的例子中是if)调用gps管理器的行时,alertmanager的弱引用将在构造函数(所有引用都已填充)和doInBackground(alertmanager引用为null,其他2个仍然填充)之间的asynctask中变为null,从而导致应用程序崩溃

当我不注释出应用程序是否正常时


警报管理器信息

这是alertmanager中调用异步任务的方法。参考资料都填在这个地方

public void GetAlerts(List<WeakReference<e_Alerts>> callbackReferences, Context context) {
    //Update the alerts in the listview and mapview with the local alerts.
    List<Alert> localAlerts = internalDc.GetAllAlerts();
    try {
        for (WeakReference<e_Alerts> callback : callbackReferences) {
            callback.get().UpdateAlerts(localAlerts);
        }
    } catch (Exception e) {
        Log.e("AlertManager", e.getMessage());
    }

    //If connected to the internet then update the local db and the views
    if (isConnectingToInternet(context)) {
        WeakReference<e_Alerts> wr = new WeakReference<e_Alerts>(this);
        callbackReferences.add(wr);

        // Update the alerts where no location is needed for so the user has a quick result
        externalDc.getAlerts(callbackReferences, areaManager.GetActiveAreas(false));

        // If gps region is enabled then find the phones location and update the alerts
        if (areaManager.GetGpsArea().IsActive()) {
            new GpsManager(this.context, this, callbackReferences);
        }
    }
}
侦听器由Alertmanager实现

// This method is caled by the GPS Manager when the GPS location is changed
    @Override
    public void OnLocationChanged(Location location, List<WeakReference<e_Alerts>> references) {Area gpsArea = areaManager.GetGpsArea();
        gpsArea.SetLocation(location);
        areaManager.SaveArea(gpsArea);
        externalDc.getAlerts(references, areaManager.GetActiveAreas(true));
    }
onPostExecute方法:

当程序采用此方法时,
this.references.get(2)
reference(alertmanager reference)=null,其他2个引用仍然被归档

@覆盖
受保护的void onPostExecute(字符串xml){
for(WeakReference参考:活动WeakReferences)
{
reference.get().updatelerts(this.result);
}
}
过滤法:

private List<Item> filterAlerts(List<Item> alerts) {
    List<Item> filteredXmlAlerts = new ArrayList<>();

    for (Item alert : alerts)
    {
        Location alertLocation = new Location("");
        alertLocation.setLatitude(alert.getGeometries().get(0).getLocations().get(0).getLat());
        alertLocation.setLongitude(alert.getGeometries().get(0).getLocations().get(0).getLng());

        for(Area area : this.mAreas)
        {
            if (area.IsOrganization() && alert.getCountryCode().toLowerCase().equals(area.getOrganizationcode().toLowerCase())){
                filteredXmlAlerts.add(alert);
                break;
            }
            else if(!area.IsOrganization() && isAlertInRegion(alertLocation, area)) {
                filteredXmlAlerts.add(alert);
                break;
            }
        }
    }
    return filteredXmlAlerts;
}
专用列表过滤器(列表警报){
List filteredXmlAlerts=new ArrayList();
用于(项目警报:警报)
{
位置警报位置=新位置(“”);
alertLocation.setLatitude(alert.getGeometries().get(0.getLocations().get(0.getLat));
alertLocation.SetLength(alert.getGeometries().get(0.getLocations().get(0.getLng));
用于(区域:this.mAreas)
{
if(area.IsOrganization()&&alert.getCountryCode().toLowerCase().equals(area.getOrganizationcode().toLowerCase()){
filteredXmlAlerts.add(警报);
打破
}
如果(!area.isoorganization()&&isAlertInRegion(alertLocation,area)){
filteredXmlAlerts.add(警报);
打破
}
}
}
返回filteredXmlAlerts;
}

我的问题

  • 我认为Weakreference是引用asynctask的正确方法,这是正确的还是我需要将其作为其他对象提供?(类、对象或其他?)

  • 为什么我的引用是空的?三个中只有一个?只有当我不使用gps定位类时?如何解决这个问题

  • 我读了一些关于垃圾收集器的文章,什么可能是这个问题的原因,这是真的吗?如果是,我如何解决这个问题


如果Answare很容易理解,那就好了,因为android对我来说是全新的。

问题2的答案是“因为Weakreference”。#3的答案是:“没什么,GC会回收你不再使用的任何东西(无法访问的对象)”,谢谢你的回答,但这不是问题2和3的完整答案,因为我需要知道如何解决这个问题。我使用参考资料,对吗?在我看来,我使用它们进行回调?为什么有一个
列表
,什么是
Reference wr=newreference()?另外,要处理弱引用,您必须检查它们是否为空,因为这是您所期望的。否则不要使用它们。对不起,引用是用于测试的,我复制了错误的代码,在我的项目中它又是一个WeakReference。我会更新我的问题好的,我知道我可以检查它们是否为null,但是当它们自发地为null时,我永远不能确定回调是否发生在alert manager类上。既然这很重要,我需要一个100%确定的工作方法,我如何提供这个?(没有内存泄漏之类的)直接存储
e_Alert
对象的列表,而不是对它们的弱引用。如果希望垃圾收集器能够回收弱引用,则仅使用弱引用。这可能意味着您需要实现某种功能来注销警报,并将其从列表中删除,但前提是这是您需要的功能。
public At_allAlerts(List<WeakReference<e_Alerts>> callbackReferences, List<Area> areas) {
    this.mCallbackReferences = callbackReferences;
    this.mAreas = areas;
}
@Override
protected String doInBackground(String... inputUrl) {
    Log.i("At_allAlerts", "Asynctask for downloading and parsing mAlerts is started");
    try {
        //Downloads the alert XMLs from the internet and parses it to xmlAlerts
        this.mAlerts = new XmlDownloader().DownloadAlerts(inputUrl);
        // Filters the mXml mAlerts so only the mAlerts where the enduser is interessed in will remain
        this.mAlerts = filterAlerts(this.mAlerts);
        // Converts the remaining xmlAlerts to Alerts;
        this.mResult = new AlertConverter().Convert(this.mAlerts);
    }catch (Exception e) {
        Log.e("At_allAlerts",e.getMessage());
    }
    return null;
}
@Override
protected void onPostExecute(String xml){
    for (WeakReference<e_Alerts> reference : activityWeakReferences)
    {
        reference.get().UpdateAlerts(this.result);
    }
}
private List<Item> filterAlerts(List<Item> alerts) {
    List<Item> filteredXmlAlerts = new ArrayList<>();

    for (Item alert : alerts)
    {
        Location alertLocation = new Location("");
        alertLocation.setLatitude(alert.getGeometries().get(0).getLocations().get(0).getLat());
        alertLocation.setLongitude(alert.getGeometries().get(0).getLocations().get(0).getLng());

        for(Area area : this.mAreas)
        {
            if (area.IsOrganization() && alert.getCountryCode().toLowerCase().equals(area.getOrganizationcode().toLowerCase())){
                filteredXmlAlerts.add(alert);
                break;
            }
            else if(!area.IsOrganization() && isAlertInRegion(alertLocation, area)) {
                filteredXmlAlerts.add(alert);
                break;
            }
        }
    }
    return filteredXmlAlerts;
}