我想异步加载图像并在信息窗口中显示它们。为此,我创建了一个自定义类来存储参数。我需要这个(标记,图像(,但我的代码抛出一个运行时异常,说它无法在我存储在自定义类实例中的标记上调用getPosition。将 AsyncTask 与自定义类实例参数一起使用的正确方法是什么?
这是我的代码:
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
LatLng latLng = marker.getPosition();
// find location id in database
Location location = dbhandler.getLocationByLatLng(latLng);
final int id = location.getId();
addButton.setVisibility(View.VISIBLE);
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// open load image fragment
android.support.v4.app.FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
LoadImageFragment fragment = new LoadImageFragment();
// pass id to new fragment
Bundle bundle = new Bundle();
bundle.putInt("id", id);
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
});
removeButton.setVisibility(View.VISIBLE);
removeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// remove markers and images
}
});
class TaskParams {
Marker marker;
Location location;
Image image;
TaskParams() {
}
public Location getLocation() {
return this.location;
}
public Marker getMarker() {
return this.marker;
}
public Image getImage(){
return this.image;
}
public void setMarker(Marker marker) {
this.marker = marker;
}
public void setLocation(Location location) {
this.location = location;
}
public void setImage(Image image) {
this.image = image;
}
}
TaskParams taskParams = new TaskParams();
taskParams.setMarker(marker);
new AsyncTask<TaskParams, Void, TaskParams>() {
@Override
protected TaskParams doInBackground(TaskParams... params) {
TaskParams tParams = params[0];
Marker m = tParams.getMarker();
LatLng latLng = m.getPosition();
Location location = dbhandler.getLocationByLatLng(latLng);
tParams.setLocation(location);
return tParams;
}
// find image and text associated with Location
protected void onPostExecute(TaskParams taskParams) {
new AsyncTask<TaskParams, Void, TaskParams>() {
@Override
protected TaskParams doInBackground(TaskParams... params) {
TaskParams tParams = params[0];
Location location = tParams.getLocation();
try {
image = dbhandler.getImageByLocationId(location.getId());
tParams.setImage(image);
}
catch (Exception ex){
Log.d("debug", "failed to fetch image");
image = null;
}
return tParams;
}
@Override
protected void onPostExecute(TaskParams taskParams) {
Image image = taskParams.getImage();
// set image and description
if(image != null) {
infoImageView.setImageBitmap(image.getBitmap());
infoTextView.setText(image.getDescription());
Marker marker = taskParams.getMarker();
marker.showInfoWindow();
updateInfoWindow(image);
}
}
}.execute(taskParams);
}
}.execute(taskParams);
//marker.showInfoWindow();
return true;
}
});
// find Location in database
// Setting a custom info window adapter for the google map
googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
// Use default InfoWindow frame
@Override
public View getInfoWindow(Marker arg0) {
return null;
}
// Defines the contents of the InfoWindow
@Override
public View getInfoContents(Marker arg0) {
// Getting view from the layout file info_window_layout
View v = getActivity().getLayoutInflater().inflate(R.layout.info_window_layout, null);
// Getting the position from the marker
final LatLng latLng = arg0.getPosition();
infoImageView = (ImageView) v.findViewById(R.id.infoImage);
infoTextView = (TextView) v.findViewById(R.id.infoText);
if(image != null) {
infoImageView.setImageBitmap(image.getBitmap());
infoTextView.setText(image.getDescription());
}
return v;
}
});
您可以重写构造函数。像这样:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
public MyAsyncTask(boolean showLoading) {
super();
// do stuff
}
// doInBackground() et al.
}
然后,在调用任务时,执行以下操作:
new MyAsyncTask(true).execute(maybe_other_params);
这比创建成员变量更有用,因为它简化了任务调用。将上面的代码与以下代码进行比较:
MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();