#android
#Android
Вопрос:
когда я запускаю свое кодирование, появляется сообщение об ошибке: только исходный поток, создавший иерархию представлений, может касаться своих представлений. и значение, полученное из ReadDataNodeTask, не отображается. как это исправить? пожалуйста, помогите мне.
и это мой код:
package com.farid.starsmaps.rute;
public class RuteActivity extends AppCompatActivity implements View.OnClickListener, OnMapReadyCallback, TaskLoadedCallback,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
TextView TextLatitude, TextLongitude, TextTujuan, Status_Asal, TextLatAwal, TextLonAwal,
TextLatAkhir, TextLonAkhir, TextJarak, TextNamaNodeAwal, TextNamanNodeAkhir, TextJarakNode;
String latitude, longitude, tujuan, lat_awal, lon_awal, lat_akhir, lon_akhir;
ListView list;
Button BtnHitung;
List<String> valueIdNode = new ArrayList<String>();
List<String> valueNamaNode = new ArrayList<String>();
List<String> valueLatitude = new ArrayList<String>();
List<String> valueLongitude = new ArrayList<String>();
ProgressDialog pDialog;
JSONArray JsonArrayNode = null;
JSONArray daftarNodeAwal, daftarNodeAkhir, daftarJarak = null;
private GoogleMap mMap;
private List<LocationModel> mListMarker = new ArrayList<>();
private Polyline currentPolyline;
private MarkerOptions place1, place2;
GoogleApiClient mGoogleApiClient;
JSONParser jParser = new JSONParser();
private Marker mCurrLocationMarker;
Spinner spinnerTujuan;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rute);
//getJSON(Konfigurasi.URL_READ_TOKO);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
list = findViewById(R.id.ListJalur);
TextLatitude = findViewById(R.id.TxtLat);
TextLongitude = findViewById(R.id.TxtLon);
TextTujuan = findViewById(R.id.TxtTujuan);
Status_Asal = findViewById(R.id.StatusAsal);
BtnHitung = findViewById(R.id.ButtonHitung);
TextLatAwal = findViewById(R.id.Lat_awal);
TextLonAwal = findViewById(R.id.Lon_awal);
TextLatAkhir = findViewById(R.id.Lat_akhir);
TextLonAkhir = findViewById(R.id.Lon_akhir);
TextJarak = findViewById(R.id.TxtJarak);
TextNamaNodeAwal= findViewById(R.id.TxtNamaNodeAwal);
TextNamanNodeAkhir= findViewById(R.id.TxtNamaNodeAkhir);
TextJarakNode = findViewById(R.id.TxtJarakNode);
spinnerTujuan = findViewById(R.id.SpinnerTujuan);
latitude = TextLatitude.getText().toString();
longitude = TextLongitude.getText().toString();
BtnHitung.setOnClickListener(this);
new ReadDataNodeTask().execute();
//Mengolah data lokasi menggunakan GPS
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
try {
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 101);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onClick(View v) {
tujuan = TextTujuan.getText().toString();
latitude = TextLatitude.getText().toString();
longitude = TextLongitude.getText().toString();
boolean isEmptyFields = false;
if (TextUtils.isEmpty(latitude)){
isEmptyFields = true;
TextLatitude.setError("Latitude Asal belum didapat");
}
if (TextUtils.isEmpty(longitude)){
isEmptyFields = true;
TextLongitude.setError("Longitude Asal belum didapat");
}
if (!isEmptyFields) {
Status_Asal.setText("Koordinat Asal telah didapat");
new ReadDataNodeTask().execute();
new ReadJarak().execute();
double lat11 = Double.parseDouble((String) TextLatAwal.getText().toString().trim());
double long11 = Double.parseDouble((String) TextLonAwal.getText().toString().trim());
double lat22 = Double.parseDouble((String) TextLatAkhir.getText().toString().trim());
double long22 = Double.parseDouble((String) TextLonAkhir.getText().toString().trim());
String nawal = TextNamaNodeAwal.getText().toString().trim();
String nakhir = TextNamanNodeAkhir.getText().toString().trim();
DecimalFormat df = new DecimalFormat("#.###");
mMap.clear();
LatLng awal = new LatLng(lat11, long11);
LatLng akhir = new LatLng(lat22, long22);
mMap.addMarker(new MarkerOptions().position(awal).title(nawal));
mMap.addMarker(new MarkerOptions().position(akhir).title(nakhir));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(awal,10));
double j = 111.319;
double euclid = (sqrt(pow((lat11 - lat22), 2) pow((long11 - long22), 2))) * j;
String h = String.valueOf(df.format(euclid));
String koma = String.valueOf(TextJarakNode.getText());
String hasil = h.substring(-3);
TextJarak.setText(h " Km");
System.out.println("Jarak Node = " hasil);
//getAllDataLocationLatLng();
place1 = new MarkerOptions().position(awal).title("Location 1");
place2 = new MarkerOptions().position(akhir).title("Location 2");
String url = getUrl(place1.getPosition(), place2.getPosition(),"driving");
new FetchURL(RuteActivity.this).execute(url,"driving");
}
}
private String getUrl(LatLng origin, LatLng dest, String directionMode) {
double lat11 = Double.parseDouble((String) TextLatAwal.getText().toString().trim());
double long11 = Double.parseDouble((String) TextLonAwal.getText().toString().trim());
double lat22 = Double.parseDouble((String) TextLatAkhir.getText().toString().trim());
double long22 = Double.parseDouble((String) TextLonAkhir.getText().toString().trim());
// Origin of route
String str_origin = "origin=" lat11 "," long11;
// Destination of route
String str_dest = "destination=" lat22 "," long22;
// Mode
String mode = "mode=" directionMode;
// Building the parameters to the web service
String parameters = str_origin "amp;" str_dest "amp;avoid=tollsamp;" mode;
// Output format
//String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/json" "?" parameters "amp;key=AIzaSyBTVcGt2fegGE6taEgiwhrQL7QWU5dgJC0";
return url;
}
@Override
public void onTaskDone(Object... values) {
if (currentPolyline != null)
currentPolyline.remove();
currentPolyline = mMap.addPolyline((PolylineOptions) values[0]);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Memulai Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected void buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
mGoogleApiClient.connect();
}
private void getAllDataLocationLatLng(){
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Menampilkan data marker ..");
dialog.show();
ApiNodeService apiComeService = ApiClient.getClient().create(ApiNodeService.class);
Call<ListLocationModel> call = apiComeService.getAllLocation();
call.enqueue(new Callback<ListLocationModel>() {
@Override
public void onResponse(Call<ListLocationModel> call, retrofit2.Response<ListLocationModel> response) {
dialog.dismiss();
mListMarker = response.body().getmData();
initMarker(mListMarker);
}
@Override
public void onFailure(Call<ListLocationModel> call, Throwable t) {
dialog.dismiss();
Toast.makeText(RuteActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void initMarker(List<LocationModel> listData){
double latAwal = Double.parseDouble((String) TextLatAwal.getText());
double lonAwal = Double.parseDouble((String) TextLonAwal.getText());
double latAkhir = Double.parseDouble((String) TextLatAkhir.getText());
double lonAkhir = Double.parseDouble((String) TextLonAkhir.getText());
LatLng awal = new LatLng(latAwal, lonAwal);
LatLng akhir = new LatLng(latAkhir, lonAkhir);
mMap.addMarker(new MarkerOptions().position(awal));
mMap.addMarker(new MarkerOptions().position(akhir));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(awal,10));
//iterasi semua data dan tampilkan markernya
// for (int i = 0; i < mListMarker.size(); i ) {
// //set latlng nya
// LatLng location = new LatLng(Double.parseDouble(mListMarker.get(i).getLatitude()), Double.parseDouble(mListMarker.get(i).getLongitude()));
// //tambahkan markernya
// Marker markers = mMap.addMarker(new MarkerOptions().position(location).title(mListMarker.get(i).getNode()));
// //set latlng index ke 0
// LatLng latLng = new LatLng(-7.346961, 112.739786);
// //lalu arahkan zooming ke marker index ke 0
// mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latLng.latitude, latLng.longitude), 11.0f));
// String str_origin = "origin=" TextLatAwal "," TextLonAwal;
// String str_dest = "destination=" TextLatAkhir "," TextLonAkhir;
// String sensor = "sensor=false";
// String parameters = str_origin "amp;" str_dest "amp;" sensor;
// String output = "json";
// String url = "https://maps.googleapis.com/maps/api/directions/" output "?" parameters "amp;key=" getString(R.string.google_maps_key);
//
// Log.d("onMapClick", url.toString());
// FetchUrl FetchUrl = new FetchUrl();
// FetchUrl.execute(url);
// }
}
@Override
public void onConnected(@Nullable Bundle bundle) {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
if (location !=null){
TextLatitude.setText(String.valueOf(location.getLatitude()));
TextLongitude.setText(String.valueOf(location.getLongitude()));
Location mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(latLng.latitude, latLng.longitude)).zoom(16).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
//menghentikan pembaruan lokasi
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
}
@SuppressLint("StaticFieldLeak")
class ReadDataNodeTask extends AsyncTask<String, String, String> {
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(RuteActivity.this);
pDialog.setMessage("Mengambil koordinat Node Tujuan...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... sText) {
Rute tempMarkerAwal = new Rute();
List<NameValuePair> parameter = new ArrayList<NameValuePair>();
try {
JSONObject json = jParser.makeHttpRequest(Konfigurasi.URL_NODE_AWAL,"POST", parameter);
Log.d("Response: ", "> " json);
int success = json.getInt(Konfigurasi.TAG_SUCCESS);
if (success == 1) { //Ada record Data (SUCCESS = 1)
//Getting Array of daftar_mhs
daftarNodeAwal = json.getJSONArray(Konfigurasi.TAG_NODE_AWAL);
//looping through All daftar_mhs
for (int i = 0; i < daftarNodeAwal.length() ; i ){
JSONObject c = daftarNodeAwal.getJSONObject(i);
//tempMarkerAwal = new Rute();
String id_node = tempMarkerAwal.setId_Node(c.getString(Konfigurasi.TAG_ID_NODE));
String nama_awal = tempMarkerAwal.setNama_Node(c.getString(Konfigurasi.TAG_NAMA_AWAL));
String lat_node_awal= tempMarkerAwal.setLat_Node(c.getString(Konfigurasi.TAG_LAT_NODE));
String lon_node_awal= tempMarkerAwal.setLon_Node(c.getString(Konfigurasi.TAG_LON_NODE));
TextNamaNodeAwal.setText(nama_awal);
TextLatAwal.setText(lat_node_awal);
TextLonAwal.setText(lon_node_awal);
}
return "OK";
}else{
//Tidak Ada Record Data (SUCCESS = 0)
return "no results";
}
} catch (Exception e) {
e.printStackTrace();
return "Exception Caught";
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
if(result.equalsIgnoreCase("Exception Caught")){
Toast.makeText(RuteActivity.this, "Gagal mengambil data node, tidak bisa terhubung ke server", Toast.LENGTH_LONG).show();
}
if(result.equalsIgnoreCase("no results")){
Toast.makeText(RuteActivity.this, "Data empty", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(RuteActivity.this, "Data node sudah muncul", Toast.LENGTH_LONG).show();
}
new getDataNodeTujuan().execute();
}
}
@SuppressLint("StaticFieldLeak")
private class getDataNodeTujuan extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(RuteActivity.this);
pDialog.setMessage("Mengambil data...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
//Membuat Service "ServiceHandler"
NodeHandler ah = new NodeHandler();
// Memanggil URL untuk mendapatkan respon data
String jsonStr = ah.makeServiceCall(Konfigurasi.URL_READ_NODE, NodeHandler.GET); //siswaManager.php?mode=getAllDataSiswa
Log.d("Response: ", "> " jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Mendapatkan data Array JSON
JsonArrayNode = jsonObj.getJSONArray("values");
ArrayList<Node> listDataNode = new ArrayList<Node>();
listDataNode.clear();
//Melakukan perulangan untuk memecah data
for (int i = 0; i < JsonArrayNode.length(); i ) {
JSONObject obj = JsonArrayNode.getJSONObject(i);
Node node = new Node();
node.setIdNode(obj.getString("id_node"));
node.setNamaNode(obj.getString("nama_node"));
node.setLatitude(obj.getString("latitude"));
node.setLongitude(obj.getString("longitude"));
listDataNode.add(node);
}
valueIdNode = new ArrayList<String>();
valueNamaNode = new ArrayList<String>();
valueLatitude = new ArrayList<String>();
valueLongitude = new ArrayList<String>();
for (int i = 0; i < listDataNode.size(); i ) {
valueIdNode.add(listDataNode.get(i).getIdNode());
valueNamaNode.add(listDataNode.get(i).getNamaNode());
valueLatitude.add(listDataNode.get(i).getLatitude());
valueLongitude.add(listDataNode.get(i).getLongitude());
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
// Membuat adapter untuk spinner
ArrayAdapter<String> spinnerAdapterNode = new ArrayAdapter<String>(RuteActivity.this,
android.R.layout.simple_spinner_item, valueNamaNode);
spinnerAdapterNode.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//Mengaitkan adapter spinner dengan spinner yang ada di layout
spinnerTujuan.setAdapter(spinnerAdapterNode);
spinnerTujuan.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
String IdNode = valueIdNode.get(position);
String NamaNode = valueNamaNode.get(position);
String Latitude = valueLatitude.get(position);
String Longitude = valueLongitude.get(position);
TextTujuan.setText(IdNode);
TextLatAkhir.setText(Latitude);
TextLonAkhir.setText(Longitude);
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
new UpdateNodeAwal().execute();
}
}
@SuppressLint("StaticFieldLeak")
class UpdateNodeAwal extends AsyncTask<String, Void, String>{
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(RuteActivity.this);
pDialog.setMessage("Mohon Tunggu..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... sText) {
List<NameValuePair> parameter = new ArrayList<NameValuePair>();
try {
JSONObject json = jParser.makeHttpRequest(Konfigurasi.URL_UPDATE_AWAL,"POST", parameter);
int success = json.getInt(Konfigurasi.TAG_SUCCESS);
if (success == 1) {
return "OK";
} else {
return "FAIL";
}
} catch (Exception e) {
e.printStackTrace();
return "Exception Caught";
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
if(result.equalsIgnoreCase("Exception Caught")){
Toast.makeText(RuteActivity.this, "Gagal Mengupdate node awal, tidak bisa terhubung ke server", Toast.LENGTH_LONG).show();
}
if(result.equalsIgnoreCase("FAIL")){
Toast.makeText(RuteActivity.this, "Gagal, Coba lagi...!!!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(RuteActivity.this, "Node awal terupdate", Toast.LENGTH_LONG).show();
}
new UpdateDataAwalAkhir().execute();
}
}
//fungsi create data
@SuppressLint("StaticFieldLeak")
class UpdateDataAwalAkhir extends AsyncTask<String, Void, String>{
ProgressDialog pDialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(RuteActivity.this);
pDialog.setMessage("Mohon Tunggu..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected String doInBackground(String... sText) {
List<NameValuePair> parameter = new ArrayList<NameValuePair>();
parameter.add(new BasicNameValuePair(Konfigurasi.TAG_TUJUAN, tujuan));
parameter.add(new BasicNameValuePair(Konfigurasi.TAG_LATITUDE, latitude));
parameter.add(new BasicNameValuePair(Konfigurasi.TAG_LONGITUDE, longitude));
try {
JSONObject json = jParser.makeHttpRequest(Konfigurasi.URL_INPUT,"POST", parameter);
int success = json.getInt(Konfigurasi.TAG_SUCCESS);
if (success == 1) {
return "OK";
} else {
return "FAIL";
}
} catch (Exception e) {
e.printStackTrace();
return "Exception Caught";
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
if(result.equalsIgnoreCase("Exception Caught")){
Toast.makeText(RuteActivity.this, "Gagal Mengupdate data, tidak bisa terhubung ke server", Toast.LENGTH_LONG).show();
}
if(result.equalsIgnoreCase("FAIL")){
Toast.makeText(RuteActivity.this, "Gagal, Coba lagi...!!!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(RuteActivity.this, "Sukses", Toast.LENGTH_LONG).show();
}
}
}
}
и когда я запускаю свой код, появляется сообщение об ошибке. ошибка заключается в том, что только исходный поток, создавший иерархию представлений, может касаться своих представлений.
как это исправить?
Комментарии:
1. Не могли бы вы, пожалуйста, поделиться журналом ошибок?
Ответ №1:
Метод doInBackground в вашей ReadDataNodeTask выполняет логику пользовательского интерфейса в фоновом потоке:
TextNamaNodeAwal.setText(nama_awal);
TextLatAwal.setText(lat_node_awal);
TextLonAwal.setText(lon_node_awal);
Вы должны обернуть любую логику пользовательского интерфейса здесь в обработчик:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
// your UI code goes here
}
});
Смотрите документацию для получения дополнительной информации о потоковой передаче в AsyncTask: https://developer.android.com/reference/android/os/AsyncTask#the-4-steps
Ответ №2:
Это просто потому, что вы выполняете пользовательский интерфейс, связанный с doInBackground(Params...)
AsyncTask.
Вы делаете следующее:
class ReadDataNodeTask extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... sText) {
...
// you must not do the UI changes here
TextNamaNodeAwal.setText(nama_awal);
TextLatAwal.setText(lat_node_awal);
TextLonAwal.setText(lon_node_awal);
...
}
}
Вы должны делать это внутри onPostExecute(Result)
:
class ReadDataNodeTask extends AsyncTask<String, String, String> {
...
protected void onPostExecute(String result) {
// should doing the UI changes inside this method.
}
}