AsyncTask阻止UI线程

时间:2018-03-21 17:27:55

标签: java android multithreading android-activity android-asynctask

我知道这里有一些类似的问题,但它们似乎都没有回答我的问题。

我的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);

}

0 个答案:

没有答案