我知道这里有一些类似的问题,但它们似乎都没有回答我的问题。
我的MainActivity
调用我的AsyncTask
,如下所示:
new ParkLoader(MainActivity.this, new OnLoadCompleted() {
@Override
public void onLoadCompleted(ArrayList<Park> parks) {
showList(parks);
}
}).execute();
OnLoadCompleted
是在AsyncTask
中调用的接口。 AsyncTask看起来像这样:
public class ParkLoader extends AsyncTask<Void, Void, Void> implements ActivityCompat.OnRequestPermissionsResultCallback {
public ParkLoader(Activity activity, OnLoadCompleted listener) {
this.activity = activity;
this.listener = listener;
}
@Override
protected Void doInBackground(Void... voids) {
if (isServicesEnabled())
findNearbyParks();
else
findParks();
return null;
}
[...]
FindParks()方法负责调用OnLoadCompleted。现在我的问题是,每次MainActivity调用AsyncTask时,它都会冻结UI线程。 AsyncTask使用Activity
引用(因为我看到对Activity的Context
的引用已知会导致UI冻结),但是不会对UI进行任何更新。
非常感谢任何帮助。
编辑:AsyncTask中的代码:
private void findNearbyParks() {
locationProvider = LocationServices.getFusedLocationProviderClient(activity);
try {
if (locationPermissionsGranted) {
final Task location = locationProvider.getLastLocation();
location.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(Object o) {
Location currentLocation = (Location) location.getResult();
ArrayList<Park> parks = getParks();
if (currentLocation != null)
for (int i = 0; i < parks.size(); i++)
parks.get(i).setDistance(Distance.getDistance(currentLocation.getLatitude(), currentLocation.getLongitude(), parks.get(i)));
else {
for (int i = 0; i < parks.size(); i++)
parks.get(i).setDistance(-1);
showLocationError();
}
Collections.sort(parks, new Comparator<Park>() {
@Override
public int compare(Park park, Park other) {
return (int) (park.distance - other.distance);
}
});
listener.onLoadCompleted(parks);
}
});
} else {
getLocationPermission();
}
} catch (SecurityException e) {
e.printStackTrace();
}
}
showList()中的代码(主要是ArrayAdapter):
void showList(final ArrayList<Park> parks) {
swipeRefreshLayout.setRefreshing(false);
finalParkList = parks;
ArrayAdapter<Park> adapter = new ArrayAdapter<Park>(this, 0, parks) {
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Park park = parks.get(position);
if (convertView == null)
convertView = getLayoutInflater().inflate(R.layout.list_item_park, null, false);
TextView nameView = convertView.findViewById(R.id.nameView);
TextView typeView = convertView.findViewById(R.id.typeView);
TextView distanceView = convertView.findViewById(R.id.distanceView);
nameView.setText(park.name);
typeView.setText(park.type);
if (park.distance != -1)
distanceView.setText(Distance.formatDistance(park.distance) + " entfernt");
else
distanceView.setVisibility(View.GONE);
return convertView;
}
};
parkListView.setAdapter(adapter);
}