简体   繁体   中英

Android Http Asynctask issue

I have develop a search function which accept two parameters from users, pass the parameters to php server, and perform sql query with the parameters. I have successfully retrieve data from database based on the parameters but my app clash when it wanted to display the result. i cannot figure out my errors in the coding, can anyone help me? thank you.

PHP

<?php

$response = array();

require_once 'include/db_connect.php';

$db = new DB_CONNECT();

if (isset($_GET["location"]) && isset($_GET["category"]) ) {

$location = $_GET['location'];
$category = $_GET['category'];

$result = mysql_query("SELECT *FROM image_detail WHERE category = '$category' AND location = '$location'");

    if (mysql_num_rows($result) > 0) {

        $response["products"] = array();

        while ($row = mysql_fetch_array($result)) {

            $product = array();
            $product["uid"] = $row["uid"];
            $product["itemname"] = $row["itemname"];
            $product["price"] = $row["price"];
            $product["description"] = $row["description"];
            $product["path"] = $row["path"];
            $timestamp = $row["posted_at"];

            $now = date('m/d/Y h:i:s a', time());
            $product["posted_at"] = xTimeAgo($timestamp, $now, "x");

            // push single product into final response array
            array_push($response["products"], $product);
        }
        // success
        $response["success"] = 1;

        // echoing JSON response
        echo json_encode($response);
    } else {
        // no product found
        $response["success"] = 0;
        $response["message"] = "No product table found";

        // echo no users JSON
        echo json_encode($response);
    }


} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";

// echoing JSON response
echo json_encode($response);
}

function xTimeAgo ($oldTime, $newTime, $timeType) {
    $timeCalc = strtotime($newTime) - strtotime($oldTime);        
    if ($timeType == "x") {
        if ($timeCalc < 60) {
            $timeType = "s";            
        }
        if ($timeCalc > 60) {
            $timeType = "m";
        }
        if ($timeCalc > (60*60)) {
            $timeType = "h";
        }
        if ($timeCalc > (60*60*24)) {
            $timeType = "d";
        }
    }        
    if ($timeType == "s") {
        $timeCalc .= " seconds ago";
    }
    if ($timeType == "m") {
        $timeCalc = round($timeCalc/60) . " minutes ago";
    }        
    if ($timeType == "h") {
        $timeCalc = round($timeCalc/60/60) . " hours ago";
    }
    if ($timeType == "d") {
        $timeCalc = round($timeCalc/60/60/24) . " days ago";
    }        
    return $timeCalc;
}
?>

Search.java

public class Search extends Activity implements OnItemSelectedListener {

private Spinner searchCategory, searchLocation;
private Button search;
ListView list;

private SweetAlertDialog pDialog;

LazyAdapter adapter;

ArrayList<HashMap<String, String>> productsList;

JSONArray products = null;

private String [] Category = {"IT Gadgets","Men Fashion","Women Fashion","Beauty","Sports","Cars and Motors","Furnitures","Music Instrument","Books","Property","Photography","Games and Toys","kids and Baby","Health", "Others"};
private String [] Location = {"Kuala Lumpur","Melacca","Johor","Selangor","Kelantan","Kedah","Negeri Sembilan","Pahang","Perak","Perlis","Penang","Sabah","Sarawak","Terengganu"};

JSONParser2 jsonParser2 = new JSONParser2();

private static final String url_search_items = "http://gemini888.tk/GP_trade_api_v2/image_connect/search_items.php";

 // JSON Node names
public static final String TAG_SUCCESS = "success";
public static final String TAG_PRODUCTS = "products";
public static final String TAG_PID = "uid";
public static final String TAG_NAME = "itemname";
public static final String TAG_PRICE = "price";
public static final String TAG_PATH = "path";
public static final String TAG_TIME = "posted_at";

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

    searchCategory = (Spinner) findViewById(R.id.spin_search_category);
    searchLocation = (Spinner) findViewById(R.id.spin_search_location);
    search = (Button) findViewById(R.id.button_search);
    list = (ListView) findViewById(android.R.id.list);

    ArrayAdapter<String> adapter_Category = new ArrayAdapter<String>
    (this, android.R.layout.simple_spinner_item, Category);

    ArrayAdapter<String> adapter_Location = new ArrayAdapter<String>
    (this, android.R.layout.simple_spinner_item, Location);

    adapter_Category.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    adapter_Location.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    searchCategory.setAdapter(adapter_Category);
    searchLocation.setAdapter(adapter_Location);

    searchCategory.setOnItemSelectedListener(this);
    searchLocation.setOnItemSelectedListener(this);

    search.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            new searchItem().execute();

        }

    });

}

class searchItem extends AsyncTask<String, String, String> {

    JSONObject json = null;

    @Override
    protected void onPreExecute() {

        super.onPreExecute();
        pDialog = new SweetAlertDialog(Search.this, SweetAlertDialog.PROGRESS_TYPE);
        pDialog.getProgressHelper().setBarColor(Color.parseColor("#A5DC86"));
        pDialog.setTitleText("Loading product details...Please wait...");
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... args) {

        String selectedCategory = searchCategory.getSelectedItem().toString();
        String selectedLocation = searchLocation.getSelectedItem().toString();

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("location", selectedLocation));
        params.add(new BasicNameValuePair("category", selectedCategory));

        json = jsonParser2.makeHttpRequest(url_search_items, "GET", params);

        Log.d("Search Details", json.toString());

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // products found
                // Getting Array of Products
                products = json.getJSONArray(TAG_PRODUCTS);

                // looping through All Products
                for (int i = 0; i < products.length(); i++) {
                    JSONObject c = products.getJSONObject(i);

                    // Storing each json item in variable
                    String id = c.getString(TAG_PID);
                    String iname = c.getString(TAG_NAME);
                    String price = c.getString(TAG_PRICE);
                    String path = c.getString(TAG_PATH);
                    String posted_at = c.getString(TAG_TIME);

                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    map.put(TAG_PID, id);
                    map.put(TAG_NAME, iname);
                    map.put(TAG_PRICE, price);
                    map.put(TAG_PATH, path);
                    map.put(TAG_TIME, posted_at);
                    // adding HashList to ArrayList
                    productsList.add(map);
                }
            } else {
                // no products found
                // Launch Add New product Activity
                Intent i = new Intent(getApplicationContext(),
                        MainActivity.class);
                // Closing all previous activities
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(i);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } 
        return null;
    }

    protected void onPostExecute(String file_url) {

        pDialog.dismiss();

        runOnUiThread(new Runnable() {
            public void run() {

        adapter=new LazyAdapter(Search.this, productsList);
        list.setAdapter(adapter);

            }
        });

    }

}

@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
        long arg3) {
    // TODO Auto-generated method stub

}


@Override
public void onNothingSelected(AdapterView<?> arg0) {
    // TODO Auto-generated method stub

}

}

JSONParser.java

public class JSONParser2 {

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser2() {

}

// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
        List<NameValuePair> params) {

    // Making HTTP request
    try {

        // check for request method
        if(method == "POST"){
            // request method is POST
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

        }else if(method == "GET"){
            // request method is GET
            DefaultHttpClient httpClient = new DefaultHttpClient();
            String paramString = URLEncodedUtils.format(params, "utf-8");
            url += "?" + paramString;
            HttpGet httpGet = new HttpGet(url);

            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();
        }           

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {

            //if(!line.startsWith("<", 0)){
            //if(!line.startsWith("(", 0)){                                     
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
      //  json = json.replaceAll("db_connect.php", "");

    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(json);
        //jObj = new JSONObject(json.substring(3));
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    // return JSON String
    return jObj;

}
}

Error log

07-21 05:03:51.410: D/Search Details(917): {"success":1,"products":[{"posted_at":"20 days ago","path":"http:\/\/testing88ff8.tk\/GPFileUpload\/uploads\/hffjfi20150701_122718.jpg","uid":"49","price":"","itemname":"???????","description":""},{"posted_at":"17 days ago","path":"http:\/\/testing88ff8.tk\/GPFileUpload\/uploads\/hffjfi.jpg",
07-21 05:03:51.430: W/dalvikvm(917): threadid=16: thread exiting with uncaught exception (group=0xb2ac7ba8)
07-21 05:03:51.470: E/AndroidRuntime(917): FATAL EXCEPTION: AsyncTask #1
07-21 05:03:51.470: E/AndroidRuntime(917): Process: gemini.lobang, PID: 917
07-21 05:03:51.470: E/AndroidRuntime(917): java.lang.RuntimeException: An error occured while executing doInBackground()
07-21 05:03:51.470: E/AndroidRuntime(917):  at android.os.AsyncTask$3.done(AsyncTask.java:300)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
07-21 05:03:51.470: E/AndroidRuntime(917):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.lang.Thread.run(Thread.java:841)
07-21 05:03:51.470: E/AndroidRuntime(917): Caused by: java.lang.NullPointerException
07-21 05:03:51.470: E/AndroidRuntime(917):  at gemini.lobang.Search$searchItem.doInBackground(Search.java:159)
07-21 05:03:51.470: E/AndroidRuntime(917):  at gemini.lobang.Search$searchItem.doInBackground(Search.java:1)
07-21 05:03:51.470: E/AndroidRuntime(917):  at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-21 05:03:51.470: E/AndroidRuntime(917):  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-21 05:03:51.470: E/AndroidRuntime(917):  ... 4 more

Lazyadapter

public class LazyAdapter extends BaseAdapter {

private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;

public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    imageLoader=new ImageLoader(activity.getApplicationContext());
}


@Override
public int getCount() {
    return data.size();
}

@Override
public Object getItem(int position) {
     return position;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View vi=convertView;
    if(convertView==null)
        vi = inflater.inflate(R.layout.list_item, null);

    TextView pid = (TextView)vi.findViewById(R.id.pid);
    TextView itemname = (TextView)vi.findViewById(R.id.name);
    TextView price = (TextView)vi.findViewById(R.id.price);
    TextView time = (TextView)vi.findViewById(R.id.time);
    ImageView thumb_image = (ImageView)vi.findViewById(R.id.imageView1); 

    HashMap<String, String> song = new HashMap<String, String>();
    song = data.get(position);

    pid.setText(song.get(ProductAll.TAG_PID));
    itemname.setText(song.get(ProductAll.TAG_NAME));
    price.setText(song.get(ProductAll.TAG_PRICE));
    time.setText(song.get(ProductAll.TAG_TIME));
    imageLoader.DisplayImage(song.get(ProductAll.TAG_PATH), thumb_image); 


    Animation animation;
    animation = AnimationUtils.loadAnimation(activity, R.anim.slide);
    //animation = AnimationUtils.loadAnimation(activity, (position > lastPosition) ?
        //  R.anim.up_from_bottom : R.anim.down_from_top);
    vi.startAnimation(animation);

    return vi;
}

public void clear() {
    data.clear();
}

}
String selectedCategory = searchCategory.getSelectedItem().toString();
String selectedLocation = searchLocation.getSelectedItem().toString();

here you are trying to use local variable instead of local one just rename them as

String selCategory = searchCategory.getSelectedItem().toString();
String selLocation = searchLocation.getSelectedItem().toString();

您无法直接从doInBackground()方法启动活动,因为该活动在与UI线程不同的线程上运行。

Starting an activity inside DoInBackground() causes the problem because Asynctask has not finished doing its job,so if you want to change some text or start and activity do it in onPostExecute() .

You can implement AsyncTask inside your OnClickListener without the need to define searchItem class. Here is the code you can use:

    search.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            final JSONObject json = null;

            String selectedCategory = searchCategory.getSelectedItem().toString();
            String selectedLocation = searchLocation.getSelectedItem().toString();

            //define params outside AsyncTask
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("location", selectedLocation));
            params.add(new BasicNameValuePair("category", selectedCategory));
            // you can either use as AsyncTask<String,String,String> or AsyncTask()
            new AsyncTask(){
                @Override
                protected void onPreExecute() {

                    pDialog = new SweetAlertDialog(Search.this, SweetAlertDialog.PROGRESS_TYPE);
                    pDialog.getProgressHelper().setBarColor(Color.parseColor("#A5DC86"));
                    pDialog.setTitleText("Loading product details...Please wait...");
                    pDialog.setCancelable(true);
                    pDialog.show();
                }

                @Override
                protected Object doInBackground(Object[] params) {
                   // now you can put params as parameter in json
                    json = jsonParser2.makeHttpRequest(url_search_items, "GET", params);

                    Log.d("Search Details", json.toString());
                    return json;
                    // returned object will be directly send to onPostExecute()
                }

                @Override
                protected void onPostExecute(Object o) {
                    // cast returned object from doInBackground() to JSONObject
                    json = (JSONObject)o;
                    try {
                        // Checking for SUCCESS TAG
                        int success = json.getInt(TAG_SUCCESS);

                        if (success == 1) {
                            // products found
                            // Getting Array of Products
                            products = json.getJSONArray(TAG_PRODUCTS);

                            // looping through All Products
                            for (int i = 0; i < products.length(); i++) {
                                JSONObject c = products.getJSONObject(i);

                                // Storing each json item in variable
                                String id = c.getString(TAG_PID);
                                String iname = c.getString(TAG_NAME);
                                String price = c.getString(TAG_PRICE);
                                String path = c.getString(TAG_PATH);
                                String posted_at = c.getString(TAG_TIME);

                                // creating new HashMap
                                HashMap<String, String> map = new HashMap<String, String>();

                                // adding each child node to HashMap key => value
                                map.put(TAG_PID, id);
                                map.put(TAG_NAME, iname);
                                map.put(TAG_PRICE, price);
                                map.put(TAG_PATH, path);
                                map.put(TAG_TIME, posted_at);
                                // adding HashList to ArrayList
                                productsList.add(map);
                            }
                        } else {
                            // no products found
                            // Launch Add New product Activity
                            // you can put SEARCH.this instead of getApplicationContext()
                            Intent i = new Intent(SEARCH.this,
                                    MainActivity.class);
                            // Closing all previous activities
                            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(i);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    pDialog.dismiss();

                    runOnUiThread(new Runnable() {
                        public void run() {

                            adapter=new LazyAdapter(Search.this, productsList);
                            list.setAdapter(adapter);

                        }
                    });
                }
            }.execute();
        }
    });

I hope this solves your problem.

Change your onPostExecute() method like below:

protected void onPostExecute(String file_url) {

        if(pDialog.isShowing){
           pDialog.dismiss();
        }

        adapter=new LazyAdapter(Search.this, productsList);
        list.setAdapter(adapter);

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM