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