How to return an object from the asynctask to the main class in android

送分小仙女□ 提交于 2019-12-31 04:03:06

问题


I want to return the document to my main class but even using a global variable dosen't work it's because the asynctask didn't finish the job I think is there a solution to get an object form asynctask please ? I already tried the affectation in the onPostExecute but the object get null if i'm outside the asynctask this is the class :

    private class RequestTask extends AsyncTask<String, Void, Document> {
    protected Document doInBackground(String... url) {
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpContext localContext = new BasicHttpContext();
            HttpPost httpPost = new HttpPost(url[0]);
            HttpResponse response = httpClient.execute(httpPost,
                    localContext);
            InputStream in = response.getEntity().getContent();
            DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                    .newDocumentBuilder();

            return builder.parse(in);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(Document doc) {
        super.onPostExecute(doc);

        if (mDirectionListener != null) {
            mDirectionListener.onResponse(getStatus(doc), doc,
                    GoogleDirection.this);
        }
    }

    private String getStatus(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("status");
        Node node1 = nl1.item(0);

        if (isLogging) {
            Log.i("GoogleDirection", "Status : " + node1.getTextContent());
        }

        return node1.getTextContent();
    }
}

I tried so much solution and no one of them works ... please help me !

UPDATE : Some errors I get :

The structure of my code : ClassMain , Class GoogleDirection and innerClass is the asynctask

This is my first class that contain an inner class (Asynctask) package com.example.busmapsproject.app;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.AsyncTask;
import android.util.DisplayMetrics;
import android.util.Log;

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolylineOptions;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


@SuppressLint("NewApi")
public class GoogleDirection {
    public final static String MODE_WALKING = "walking";
    private OnDirectionResponseListener mDirectionListener = null;
    private boolean isLogging = false;
    private Context myContext = null;
    private Document test;

    public GoogleDirection(Context context) {
        myContext = context;
    }

    public String request(LatLng start, LatLng end, String mode) {
        final String url = "http://maps.googleapis.com/maps/api/directions/xml?" +
            "origin=" + start.latitude + "," + start.longitude +
            "&destination=" + end.latitude + "," + end.longitude +
            "&sensor=false&units=metric&mode=" + mode;

        if (isLogging) {
            //Display information in logcat (report success)
            Log.i("GoogleDirection", "URL : " + url);
        }

            new RequestTask().execute(url);


        return url;
    }

    public void setLogging(boolean state) {
        isLogging = state;
    }

    public String getStatus(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("status");
        Node node1 = nl1.item(0);

        if (isLogging) {
            Log.i("GoogleDirection", "Status : " + node1.getTextContent());
        }

        return node1.getTextContent();
    }

    public String[] getDurationText(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("duration");
        String[] arr_str = new String[nl1.getLength() - 1];

        for (int i = 0; i < (nl1.getLength() - 1); i++) {
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes(); //Return child of a node (Duration have text and value)
            Node node2 = nl2.item(getNodeIndex(nl2, "text"));
            arr_str[i] = node2.getTextContent();

            if (isLogging) {
                Log.i("GoogleDirection",
                    "DurationText : " + node2.getTextContent());
            }
        }

        return arr_str;
    }

    public int[] getDurationValue(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("duration");
        int[] arr_int = new int[nl1.getLength() - 1];

        for (int i = 0; i < (nl1.getLength() - 1); i++) {
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "value"));
            arr_int[i] = Integer.parseInt(node2.getTextContent());

            if (isLogging) {
                Log.i("GoogleDirection", "Duration : " +
                    node2.getTextContent());
            }
        }

        return arr_int;
    }

    public String getTotalDurationText(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("duration");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "text"));

        if (isLogging) {
            Log.i("GoogleDirection", "TotalDuration : " +
                node2.getTextContent());
        }

        return node2.getTextContent();
    }

    public int getTotalDurationValue(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("duration");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));

        if (isLogging) {
            Log.i("GoogleDirection", "TotalDuration : " +
                node2.getTextContent());
        }
        return Integer.parseInt(node2.getTextContent());
    }

    public String[] getDistanceText(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("distance");
        String[] arr_str = new String[nl1.getLength() - 1];

        for (int i = 0; i < (nl1.getLength() - 1); i++) {
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "text"));
            arr_str[i] = node2.getTextContent();

            if (isLogging) {
                Log.i("GoogleDirection",
                    "DurationText : " + node2.getTextContent());
            }
        }

        return arr_str;
    }

    public int[] getDistanceValue(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("distance");
        int[] arr_int = new int[nl1.getLength() - 1];

        for (int i = 0; i < (nl1.getLength() - 1); i++) {
            Node node1 = nl1.item(i);
            NodeList nl2 = node1.getChildNodes();
            Node node2 = nl2.item(getNodeIndex(nl2, "value"));
            arr_int[i] = Integer.parseInt(node2.getTextContent());

            if (isLogging) {
                Log.i("GoogleDirection", "Duration : " +
                    node2.getTextContent());
            }
        }

        return arr_int;
    }

    public String getTotalDistanceText(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "text"));

        if (isLogging) {
            Log.i("GoogleDirection", "TotalDuration : " +
                node2.getTextContent());
        }

        return node2.getTextContent();
    }

    public int getTotalDistanceValue(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("distance");
        Node node1 = nl1.item(nl1.getLength() - 1);
        NodeList nl2 = node1.getChildNodes();
        Node node2 = nl2.item(getNodeIndex(nl2, "value"));

        if (isLogging) {
            Log.i("GoogleDirection", "TotalDuration : " +
                node2.getTextContent());
        }

        return Integer.parseInt(node2.getTextContent());
    }

    public String getStartAddress(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("start_address");
        Node node1 = nl1.item(0);

        if (isLogging) {
            Log.i("GoogleDirection", "StartAddress : " +
                node1.getTextContent());
        }

        return node1.getTextContent();
    }

    public String getEndAddress(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("end_address");
        Node node1 = nl1.item(0);

        if (isLogging) {
            Log.i("GoogleDirection", "StartAddress : " +
                node1.getTextContent());
        }

        return node1.getTextContent();
    }

    public String getCopyRights(Document doc) {
        NodeList nl1 = doc.getElementsByTagName("copyrights");
        Node node1 = nl1.item(0);

        if (isLogging) {
            Log.i("GoogleDirection", "CopyRights : " + node1.getTextContent());
        }

        return node1.getTextContent();
    }

    public ArrayList<LatLng> getDirection(Document doc) {
        NodeList nl1;
        NodeList nl2;
        NodeList nl3;
        ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
        nl1 = doc.getElementsByTagName("step");

        if (nl1.getLength() > 0) {
            for (int i = 0; i < nl1.getLength(); i++) {
                Node node1 = nl1.item(i);
                nl2 = node1.getChildNodes();

                Node locationNode = nl2.item(getNodeIndex(nl2, "start_location"));
                nl3 = locationNode.getChildNodes();

                Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
                double lat = Double.parseDouble(latNode.getTextContent());
                Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                double lng = Double.parseDouble(lngNode.getTextContent());
                listGeopoints.add(new LatLng(lat, lng));

                locationNode = nl2.item(getNodeIndex(nl2, "polyline"));
                nl3 = locationNode.getChildNodes();
                latNode = nl3.item(getNodeIndex(nl3, "points"));

                ArrayList<LatLng> arr = decodePoly(latNode.getTextContent());

                for (int j = 0; j < arr.size(); j++) {
                    listGeopoints.add(new LatLng(arr.get(j).latitude,
                            arr.get(j).longitude));
                }

                locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
                nl3 = locationNode.getChildNodes();
                latNode = nl3.item(getNodeIndex(nl3, "lat"));
                lat = Double.parseDouble(latNode.getTextContent());
                lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                lng = Double.parseDouble(lngNode.getTextContent());
                listGeopoints.add(new LatLng(lat, lng));
            }
        }

        return listGeopoints;
    }

    public ArrayList<LatLng> getSection(Document doc) {
        NodeList nl1;
        NodeList nl2;
        NodeList nl3;
        ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
        nl1 = doc.getElementsByTagName("step");

        if (nl1.getLength() > 0) {
            for (int i = 0; i < nl1.getLength(); i++) {
                Node node1 = nl1.item(i);
                nl2 = node1.getChildNodes();

                Node locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
                nl3 = locationNode.getChildNodes();

                Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
                double lat = Double.parseDouble(latNode.getTextContent());
                Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                double lng = Double.parseDouble(lngNode.getTextContent());
                listGeopoints.add(new LatLng(lat, lng));
            }
        }

        return listGeopoints;
    }

    public PolylineOptions getPolyline(Document doc, int width, int color) {
        ArrayList<LatLng> arr_pos = getDirection(doc);
        PolylineOptions rectLine = new PolylineOptions().width(dpToPx(width))
                                                        .color(color);

        for (int i = 0; i < arr_pos.size(); i++)
            rectLine.add(arr_pos.get(i));

        return rectLine;
    }

    private int getNodeIndex(NodeList nl, String nodename) {
        for (int i = 0; i < nl.getLength(); i++) {
            if (nl.item(i).getNodeName().equals(nodename)) {
                return i;
            }
        }

        return -1;
    }

    private ArrayList<LatLng> decodePoly(String encoded) {
        ArrayList<LatLng> poly = new ArrayList<LatLng>();
        int index = 0;
        int len = encoded.length();
        int lat = 0;
        int lng = 0;

        while (index < len) {
            int b;
            int shift = 0;
            int result = 0;

            do {
                b = encoded.charAt(index++) - 63;
                result |= ((b & 0x1f) << shift);
                shift += 5;
            } while (b >= 0x20);

            int dlat = (((result & 1) != 0) ? (~(result >> 1)) : (result >> 1));
            lat += dlat;
            shift = 0;
            result = 0;

            do {
                b = encoded.charAt(index++) - 63;
                result |= ((b & 0x1f) << shift);
                shift += 5;
            } while (b >= 0x20);

            int dlng = (((result & 1) != 0) ? (~(result >> 1)) : (result >> 1));
            lng += dlng;

            LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
            poly.add(position);
        }

        return poly;
    }

    //Convert dp to pixel
    private int dpToPx(int dp) {
        DisplayMetrics displayMetrics = myContext.getResources()
                                                 .getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));

        return px;
    }

    public void setOnDirectionResponseListener(
        OnDirectionResponseListener listener) {
        mDirectionListener = listener;
    }

    public interface OnDirectionResponseListener {
        public void onResponse(String status, Document doc, GoogleDirection gd);
    }

    private class RequestTask extends AsyncTask<String, Void, Document> {

        protected Document doInBackground(String... url) {
            try {
                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                HttpPost httpPost = new HttpPost(url[0]);
                HttpResponse response = httpClient.execute(httpPost,
                        localContext);
                InputStream in = response.getEntity().getContent();
                DocumentBuilder builder = DocumentBuilderFactory.newInstance()
                                                                .newDocumentBuilder();

                return builder.parse(in);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            }

            return null;
        }

        protected void onPostExecute(Document doc) {
            super.onPostExecute(doc);

            if (mDirectionListener != null) {
                mDirectionListener.onResponse(getStatus(doc), doc,
                    GoogleDirection.this);
            }
        }


        private String getStatus(Document doc) {
            NodeList nl1 = doc.getElementsByTagName("status");
            Node node1 = nl1.item(0);

            if (isLogging) {
                Log.i("GoogleDirection", "Status : " + node1.getTextContent());
            }

            return node1.getTextContent();
        }
    }
}

and this is my main class : import android.graphics.Color; import android.os.Bundle; import android.support.v4.app.FragmentActivity;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import org.w3c.dom.Document;

public class MapsActivity extends FragmentActivity {

    private GoogleMap mMap; // Might be null if Google Play services APK is not available.
    private GoogleDirection gd;
    private LatLng Arret=new LatLng(30.413647, -9.555608);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        gd = new GoogleDirection(this);
        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

    /**
     * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
     * installed) and the map has not already been instantiated.. This will ensure that we only ever
     * call {@link #setUpMap()} once when {@link #mMap} is not null.
     * <p>
     * If it isn't installed {@link SupportMapFragment} (and
     * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
     * install/update the Google Play services APK on their device.
     * <p>
     * A user can return to this FragmentActivity after following the prompt and correctly
     * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
     * have been completely destroyed during this process (it is likely that it would only be
     * stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
     * method in {@link #onResume()} to guarantee that it will be called.
     */
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            mMap.setMyLocationEnabled(true);
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    /**
     * This is where we can add markers or lines, add listeners or move the camera. In this case, we
     * just add a marker near Africa.
     * <p>
     * This should only be called once and when we are sure that {@link #mMap} is not null.
     */
    private void setUpMap() {

        MyLocation loc=new MyLocation(this);
        mMap.addMarker(new MarkerOptions().position(new LatLng(loc.getLatitude(),loc.getLongitude()))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_BLUE)));
        mMap.addMarker(new MarkerOptions().position(Arret)
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_BLUE)));
        gd.setOnDirectionResponseListener(new GoogleDirection.OnDirectionResponseListener() {
            @Override
            public void onResponse(String status, Document doc, GoogleDirection gd) {
                mMap.addPolyline(gd.getPolyline(doc, 3, Color.RED));
                gd.getTotalDurationValue(doc);
            }
        });
        gd.setLogging(true);
        //LatLng test=new LatLng((loc.getLatitude()+0.1f),(loc.getLongitude()+0.5f));
        gd.request(new LatLng(loc.getLatitude(),loc.getLongitude()), Arret , GoogleDirection.MODE_WALKING);

    }
}

回答1:


Use a Listener Listener for that. Example in 2 minutes.

Use an Interface like:

public interface OnTaskCompleted{
    void onTaskCompleted(Document doc);
}

Extend your Activity with this Interface:

public YourActivity implements OnTaskCompleted{
   //your Activity
}

Let the AsyncTask send an information when it's done.

public YourTask extends AsyncTask<Object,Object,Object>{ 
private OnTaskCompleted listener;

// all your stuff
public YourTask(OnTaskCompleted listener){
    this.listener=listener;
}

protected void onPostExecute(Object o){
    listener.onTaskCompleted(doc);
}
}

Now you implement the onTaskCompleted in your activity and handle the Document which has been given by the asynctask.




回答2:


OnPostExecute is where you receive the Document when it finishes downloading in the main thread, that is the place where you want to return tour item.

It occurs to me that you can implement a constructor in the asynctask, something like

private class RequestTask extends AsyncTask<String, Void, Document> {

  private MainClass myClass

  public RequestTask(MainClass myClass){
     this.myClass = myClass
  }

...

  protected void onPostExecute(Document doc) {
    super.onPostExecute(doc);
    myClass.myMethod(doc);
  }
...
}

That way you can receive the Document in your main Class

Hope it helps

Greetings




回答3:


You could just call an other function, for example:

    protected void onPostExecute(Document doc) {
        documentIsReady(doc);
    }

}

public void documentIsReady(Document doc)
{
    //Do somehting
}


来源:https://stackoverflow.com/questions/23924483/how-to-return-an-object-from-the-asynctask-to-the-main-class-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!