无法在未在 AsyncTask 中调用 Looper.prepare() 的线程内创建处理程序



>im 试图使用安卓拥有的地理编码器获取城市 它的应用程序我们创建为家庭作业。 我正在尝试在 AsyncTask 中执行此操作,但出现以下异常:

Can't create handler inside thread that has not called Looper.prepare()

异步任务代码:

public class GeocoderTask extends AsyncTask<Void, Void, String> {
LocationManager locationManager;
Location location;
Context context;
String city;
public GeocoderTask(Context context) {
this.context = context;
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
}
@SuppressLint("MissingPermission")
@Override
protected String doInBackground(Void... voids) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
GeocoderTask.this.location = location;
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
List<Address> addresses;
try {
addresses  = geocoder.getFromLocation(GeocoderTask.this.location.getLatitude(), GeocoderTask.this.location.getLongitude(), 3);
city = addresses.get(0).getLocality();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.getMessage();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
return city;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
FrgPersonInfo frgPersonInfo = new FrgPersonInfo();
System.out.println(s);
frgPersonInfo.saveUserToTable(s);
}

}

我正在从片段调用异步任务 片段的调用:

view.findViewById(R.id.btnRegister).setOnClickListener(new View.OnClickListener() {
@SuppressLint("MissingPermission")
@Override
public void onClick(View v) {
checkPermissions();
GeocoderTask geocoderTask = new GeocoderTask(context);
geocoderTask.execute();
}
});

我在 AsyncTask 中的 onPostExecute 中调用的方法:

public void saveUserToTable(String city) {
String age = uAge.getText().toString();
String name = fName.getText().toString();
UserInfo userInfo = new UserInfo();
userInfo.setIsConnected(true);
userInfo.setUserImage(imageUrl);
userInfo.setAge(Integer.valueOf(age));
userInfo.setName(name);
userInfo.setCity(city);
Backendless.Data.of(UserInfo.class).save(userInfo, new AsyncCallback<UserInfo>() {
@Override
public void handleResponse(UserInfo response) {
System.out.println("Bitch, im here again!");
((TextView)parentView.findViewById(R.id.loginFrgBtn)).setTextColor(Color.BLUE);
((TextView)parentView.findViewById(R.id.registerFrgBtn)).setTextColor(Color.BLACK);
FragmentTransaction ft = fm.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
FrgLogin frgLogin = new FrgLogin();
ft.replace(R.id.container, frgLogin);
ft.commit();
TastyToast.makeText(context, "Welcome!", TastyToast.LENGTH_LONG, TastyToast.SUCCESS).show();
}
@Override
public void handleFault(BackendlessFault fault) {
TastyToast.makeText(context, fault.getMessage(), TastyToast.LENGTH_LONG, TastyToast.ERROR).show();
}
});
}

检查权限:

private void checkPermissions() {
List<String> neededPerms = new ArrayList<>();
int fineGpsPerm = context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
int coarseGpsPerm = context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
if (fineGpsPerm != PackageManager.PERMISSION_GRANTED || coarseGpsPerm != PackageManager.PERMISSION_GRANTED) {
neededPerms.add(Manifest.permission.ACCESS_FINE_LOCATION);
neededPerms.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!neededPerms.isEmpty()) {
ActivityCompat.requestPermissions( getActivity(), neededPerms.toArray(new String[neededPerms.size()]), GPS_PERM_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case GPS_PERM_CODE:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED|| grantResults[1] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(context, "Need to Allow perms First", Toast.LENGTH_SHORT).show();
checkPermissions();
}
break;
}
}

片段类:

public class FrgPersonInfo extends Fragment{
public static final int GPS_PERM_CODE = 103;
Context context;
EditText fName, uAge, uCity;
String imageUrl = "";
FragmentManager fm;
View parentView;
LocationManager locationManager;
Location location;
boolean isLocEnabled = false;
String cityAddress = "";

@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
this.context = context;
System.out.println("in person onattach");
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@SuppressLint("MissingPermission")
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//inflating the wanted fragmentView
View myView = inflater.inflate(R.layout.frg_person_info, container, false);
// init the fields
fName = myView.findViewById(R.id.fName);
uAge = myView.findViewById(R.id.userAge);
uCity = myView.findViewById(R.id.userCity);
fm = getActivity().getSupportFragmentManager();
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
return myView;
}
@SuppressLint("MissingPermission")
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
parentView = view.getRootView();
//creating a bundle so we can (in this case) get data
Bundle bundle = getArguments();
//use the get.. method to get data by key
//        imageUrl = bundle.getString(FrgRegister.IMAGE_KEY);
checkPermissions();
if (isLocEnabled) {
} else {
Toast.makeText(context, "dont have perms", Toast.LENGTH_SHORT).show();
}

view.findViewById(R.id.btnRegister).setOnClickListener(new View.OnClickListener() {
@SuppressLint("MissingPermission")
@Override
public void onClick(View v) {
checkPermissions();
GeocoderTask geocoderTask = new GeocoderTask(context);
geocoderTask.getUpdate();
}
});
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onDetach() {
super.onDetach();
this.fName = null;
this.uAge = null;
this.uCity = null;
this.fm = null;
this.imageUrl = null;
}

public void saveUserToTable(String city) {
String age = uAge.getText().toString();
String name = fName.getText().toString();
UserInfo userInfo = new UserInfo();
userInfo.setIsConnected(true);
userInfo.setUserImage(imageUrl);
userInfo.setAge(Integer.valueOf(age));
userInfo.setName(name);
userInfo.setCity(city);
Backendless.Data.of(UserInfo.class).save(userInfo, new AsyncCallback<UserInfo>() {
@Override
public void handleResponse(UserInfo response) {
System.out.println("Bitch, im here again!");
((TextView)parentView.findViewById(R.id.loginFrgBtn)).setTextColor(Color.BLUE);
((TextView)parentView.findViewById(R.id.registerFrgBtn)).setTextColor(Color.BLACK);
FragmentTransaction ft = fm.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
FrgLogin frgLogin = new FrgLogin();
ft.replace(R.id.container, frgLogin);
ft.commit();
TastyToast.makeText(context, "Welcome!", TastyToast.LENGTH_LONG, TastyToast.SUCCESS).show();
}
@Override
public void handleFault(BackendlessFault fault) {
TastyToast.makeText(context, fault.getMessage(), TastyToast.LENGTH_LONG, TastyToast.ERROR).show();
}
});
}

private void checkPermissions() {
List<String> neededPerms = new ArrayList<>();
int fineGpsPerm = context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
int coarseGpsPerm = context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
if (fineGpsPerm != PackageManager.PERMISSION_GRANTED || coarseGpsPerm != PackageManager.PERMISSION_GRANTED) {
neededPerms.add(Manifest.permission.ACCESS_FINE_LOCATION);
neededPerms.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (!neededPerms.isEmpty()) {
ActivityCompat.requestPermissions( getActivity(), neededPerms.toArray(new String[neededPerms.size()]), GPS_PERM_CODE);
} else {
isLocEnabled = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case GPS_PERM_CODE:
if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {
checkPermissions();
} else {
isLocEnabled = true;
}
break;
}
}
}

创建 locationListener 以保留对它的引用。

创建一个类来触发位置更新

public class GeocoderTask {
LocationManager locationManager;
Location location;
Context context;
String city;
LocationListener locationListener = new LocationListener(){
@Override
public void onLocationChanged(Location location) {
GeocoderTask.this.location = location;
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
List<Address> addresses;
FrgPersonInfo frgPersonInfo = new FrgPersonInfo();
System.out.println(city);
frgPersonInfo.saveUserToTable(s);
try {
addresses  = geocoder.getFromLocation(GeocoderTask.this.location.getLatitude(), GeocoderTask.this.location.getLongitude(), 3);
city = addresses.get(0).getLocality();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.getMessage();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
}
public GeocoderTask(Context context) {
this.context = context;
locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
}
public void getUpdate(){
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER,locationListener,null
}

你只需要创建类并使用 locationListener 调用函数 getUpdate,这将调用 Update 一次。如果需要更多更新,还可以使用 requestUpdates 并创建一个函数来删除侦听器。

Asynctask是一个线程,它只执行它应该和不需要Looper的任务,尽管没有为这个线程调用Looper。Locationlistener的工作方式与您尝试过的有所不同。 只要你不停止侦听器,OnLocationchanged就会被调用,但这是异步发生的,你不能只是在asynctask内等待它完成。您必须从主线程启动locationlistener,并且每当更改位置时,都会调用函数onLocationChanged。例如,您可以将onPostExecution放在locationlistener中。

@Override
public void onLocationChanged(Location location) {
GeocoderTask.this.location = location;
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
List<Address> addresses;
try {
addresses  = geocoder.getFromLocation(GeocoderTask.this.location.getLatitude(), GeocoderTask.this.location.getLongitude(), 3);
city = addresses.get(0).getLocality();
FrgPersonInfo frgPersonInfo = new FrgPersonInfo();
System.out.println(city);
frgPersonInfo.saveUserToTable(s);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.getMessage();
}
}

最新更新