使用 locationListener 切换到 loader

switching to loader using locationListener

我正在学习 Udacity Android 基础课程,并且正在尝试更改我的应用程序以使用 Loader 而不是 AsyncTask。我的应用程序使用 locationListener 生成一个自定义 URL,然后将其传递给加载器,加载器调用 ChargePointLoader class 来启动 HTTP 请求和 returns chargePoints 列表,它应该填充适配器一旦加载。

但是我的屏幕上什么也没有出现。我的加载器顺序是否错误,或者 locationListener 是否干扰了加载器?感谢您的帮助

这是旧异步项目的 link:https://github.com/Kovah101/ChargeMyCarBareBones/blob/master/app/src/main/java/com/example/android/chargemycar/MainActivity.java

这是我的主要内容activity

public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<ChargePoint>> {

public static final String LOG_TAG = MainActivity.class.getName();

public static double myLat;
public static double myLong;

private static  String ChargePoint_REQUEST_URL = "http://chargepoints.dft.gov.uk/api/retrieve/registry/postcode/SW15+5QS/dist/7/format/json/limit/10";

private ChargePointAdapter adapter;

private LocationManager locationManager;
private LocationListener locationListener;

private static final int CHARGEPOINT_LOADER_ID = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Find a reference to the {@link ListView} in the layout
   final ListView chargePointListView = (ListView) findViewById(R.id.list);

    // Create a ChargingPointAdapter, whose data source is a list of ChargePoints, which creates listview items for each item
    adapter = new ChargePointAdapter(this, new ArrayList<ChargePoint>());

    //possible error with order of loaders or inside listener
    final LoaderManager loaderManager = getLoaderManager();

    locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
    locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            //set lat & long variables
            myLat = location.getLatitude();
            myLong = location.getLongitude();
            String myLatString = Double.toString(myLat);
            String myLongString = Double.toString(myLong);

            //test with toast
            Context context = getApplicationContext();
            CharSequence text = " my latitude=" +myLatString +"\nmy longitude=" +myLongString ;
            int duration = Toast.LENGTH_LONG;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();

            //create request URL using live location
            ChargePoint_REQUEST_URL = "http://chargepoints.dft.gov.uk/api/retrieve/registry/lat/" +myLat + "/long/" +myLong +"/dist/10/format/json/limit/10";

            // Set the adapter on the {@link ListView}
            // so the list can be populated in the user interface
            chargePointListView.setAdapter(adapter);


            loaderManager.initLoader(CHARGEPOINT_LOADER_ID, null, MainActivity.this );

        }

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

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onProviderDisabled(String provider) {
        }
    };


    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    }else{
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 100, locationListener);
        //time in milliseconds
        //distance in meters
    }

    // On click take to maps
    chargePointListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String myLatString = Double.toString(myLat);
            String myLongString = Double.toString(myLong);

            ChargePoint currentChargePoint = (ChargePoint) chargePointListView.getItemAtPosition(position);
            double destinationLatitude = currentChargePoint.getLatitude();
            double destinationLongitude = currentChargePoint.getLongitude();
            String destLatString = Double.toString(destinationLatitude);
            String destLongString = Double.toString(destinationLongitude);


            //create uri for map intent
            String url = "http://maps.google.com/maps?saddr="+myLatString+","+myLongString+"&daddr="+destLatString+","+destLongString+"&travelmode=driving";
            Intent mapIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(url));
                mapIntent.setPackage("com.google.android.apps.maps");
                if (mapIntent.resolveActivity(getPackageManager()) != null) {
                    startActivity(mapIntent);
                }
        }
    });


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 25, locationListener);
            //time in ms, distance in meters
        }
    }
}

@Override
public Loader<List<ChargePoint>> onCreateLoader(int i, Bundle bundle) {
    return new ChargePointLoader(this, ChargePoint_REQUEST_URL);
}

@Override
public void onLoadFinished(Loader<List<ChargePoint>> loader, List<ChargePoint> chargePoints) {
    // Clear the adapter of previous data
    adapter.clear();
    //check for null charge point list, return early if that is the case, if there is a valid list then add to the adapter
    if (chargePoints != null && !chargePoints.isEmpty()){
        adapter.addAll(chargePoints);
    }
}

@Override
public void onLoaderReset(Loader<List<ChargePoint>> loader) {
    // TODO: Loader reset, so we can clear out our existing data.
    adapter.clear();
}

}

加载程序现已弃用,请将 Android 架构组件(LiveData 和 ViewModel)与旧的 AsyncTask 一起使用。与 Loader 相比,它的工作效率更高、速度更快、更清洁。它还使您的 AsyncTask 具有生命周期意识。生命周期意识在某种意义上,无论您调用 onCreate() 多少次,您的网络请求都不会再次发出,因为它会自动缓存下载的数据。配置更改不会影响您的应用。有关将 AsyncTask 与 LiveData 和 ViewModel 一起使用的更多信息,请访问 https://medium.com/androiddevelopers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4