【问题标题】:Display json to textview force close显示 json 到 textview 强制关闭
【发布时间】:2014-10-15 03:29:32
【问题描述】:

我想通过 php 显示 mysql 数据库中的产品详细信息,并在 android textview 中显示。场景是这样的:当点击产品列表时。它将产品 ID 传递给名为 productdetail 的新意图。该 id 将用于通过 php 在 mysql db 中获取详细产品。 PHP 文件已成功返回 json 格式的数据。但是当我运行程序时,它会在打开 productdetail 意图时保持强制关闭。我发现的问题是这个方法 new GetProductDetails().execute(); 这是我的代码:

getproductdetail.java

公共类 ProductDetail 扩展 Activity {

TextView txtName;
TextView txtVersion;
TextView txtDesc;
String pid;

//progress dialog
private ProgressDialog pDialog;

//Creating JSON Parser object
JSONParser jsonParser = new JSONParser();

//url to get all products list
private static String url_product_details = "http://visioinformatika.com/demo/appswitcher/bin/get_product_details.php";

// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "product_name";
private static final String TAG_VERSION = "app_version";
private static final String TAG_PDETAIL = "product_detail";

// products JSONArray
JSONArray products = null;

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

    // getting product details from intent
        Intent i = getIntent();
    // getting product id (pid) from intent
        pid = i.getStringExtra(TAG_PID);

        //txtName = (TextView) findViewById(R.id.app_name);
        //txtName.setText(pid);

    // Getting complete product details in background thread
        new GetProductDetails().execute();

}

/**
 * Background Async Task to Get complete product details
 * */
class GetProductDetails extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(ProductDetail.this);
        pDialog.setMessage("Loading product details. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    /**
     * Getting product details in background thread
     * */
    protected String doInBackground(String... params) {

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                // Check for success tag
                int success;
                try {
                    // Building Parameters
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("pid", pid));

                    // getting product details by making HTTP request
                    // Note that product details url will use GET request
                    JSONObject json = jsonParser.makeHttpRequest(
                            url_product_details, "GET", params);

                    // check your log for json response
                    Log.d("Single Product Details", json.toString());

                    // json success tag
                    success = json.getInt(TAG_SUCCESS);
                    if (success == 1) {
                        // successfully received product details
                        JSONArray productObj = json
                                .getJSONArray(TAG_PRODUCTS); // JSON Array

                        // get first product object from JSON Array
                        JSONObject product = productObj.getJSONObject(0);

                        // product with this pid found
                        // Edit Text
                        txtName = (TextView) findViewById(R.id.app_name);
                        txtVersion = (TextView) findViewById(R.id.app_version);
                        txtDesc = (TextView) findViewById(R.id.desc_app);

                        // display product data in TextView
                        txtName.setText(product.getString(TAG_NAME));
                        txtVersion.setText(product.getString(TAG_VERSION));
                        txtDesc.setText(product.getString(TAG_PDETAIL));

                    }else{
                        // product with pid not found
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once got all details
        pDialog.dismiss();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.product_detail, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

}

这是我的 php

if (isset($_GET["pid"])) {
$pid = $_GET['pid'];

// get a product from products table
$result = mysql_query("SELECT * FROM product WHERE idproduct = '".$pid."'");

if (!empty($result)) {
    // check for empty result
    if (mysql_num_rows($result) > 0) {

        $row = mysql_fetch_array($result);

        $product = array();
        $product["pid"] = $row["idproduct"];
        $product["product_name"] = $row["product_name"];
        $product["product_detail"] = $row["product_detail"];
        $product["app_version"] = $row["app_version"]; 
        // success
        $response["success"] = 1;

        // user node
        $response["product"] = array();

        array_push($response["product"], $product);

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

        // echo no users JSON
        echo json_encode($response);
    }
} else {
    // no product found
    $response["success"] = 0;
    $response["message"] = "No product 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);
}

这是我的崩溃日志

10-15 09:50:32.930: W/dalvikvm(19033): threadid=1: 线程以未捕获的异常退出 (group=0x41534ba8) 10-15 09:50:32.930:E/AndroidRuntime(19033):致命异常:主要 10-15 09:50:32.930:E/AndroidRuntime(19033):进程:com.visioinformatika.appswitcher,PID:19033 10-15 09:50:32.930: E/AndroidRuntime(19033): android.os.NetworkOnMainThreadException 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 java.net.InetAddress.lookupHostByName(InetAddress.java:385) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 java.net.InetAddress.getAllByName(InetAddress.java:214) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 10-15 09:50:32.930: E/AndroidRuntime(19033): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 10-15 09:50:32.930: E/AndroidRuntime(19033): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 com.visioinformatika.appswitcher.JSONParser.makeHttpRequest(JSONParser.java:62) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 com.visioinformatika.appswitcher.ProductDetail$GetProductDetails$1.run(ProductDetail.java:102) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 android.os.Handler.handleCallback(Handler.java:733) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 android.os.Handler.dispatchMessage(Handler.java:95) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 android.os.Looper.loop(Looper.java:136) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 android.app.ActivityThread.main(ActivityThread.java:5001) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 java.lang.reflect.Method.invokeNative(Native Method) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 java.lang.reflect.Method.invoke(Method.java:515) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 10-15 09:50:32.930: E/AndroidRuntime(19033): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 10-15 09:50:32.930: E/AndroidRuntime(19033): at dalvik.system.NativeStart.main(Native Method)

对不起,我的英语不好。我是 android 新手 :)

【问题讨论】:

  • 您认为runOnUiThread() 在您的异步任务中的作用以及它与NetworkOnMainThreadException 的关系如何?

标签: java php android json


【解决方案1】:

你必须改进你的编码风格,在onCreate中初始化视图。

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

     txtName = (TextView) findViewById(R.id.app_name);
     txtVersion = (TextView) findViewById(R.id.app_version);
     txtDesc = (TextView) findViewById(R.id.desc_app);
}

如果

您想在后台更新您的 UI,然后继续前进。

其他

doInBackground 中执行后台进程,最后在 asynTask 的 onPostExecute 中更新您的视图。

【讨论】:

  • 感谢您的建议 robbin :),我已经初始化了 textView。但是我不明白关于在PostExecute 上更新视图...你能详细解释一下吗?
【解决方案2】:

请将此代码放在postexecute方法中。UI不能填写主线程。

 // display product data in TextView
                        txtName.setText(product.getString(TAG_NAME));
                        txtVersion.setText(product.getString(TAG_VERSION));
                        txtDesc.setText(product.getString(TAG_PDETAIL));

将这一行放入 OnCreate() 中,就像 RobinHood 所说的那样......

 txtName = (TextView) findViewById(R.id.app_name);
     txtVersion = (TextView) findViewById(R.id.app_version);
     txtDesc = (TextView) findViewById(R.id.desc_app);

【讨论】:

  • 我已将该代码放入我的帖子执行中。但仍然收到错误警告。抱歉,...我是 android 新手,对 java 编程知之甚少。
  • 我已将该代码放入我的后执行方法中。但它显示错误“产品无法解析”,
【解决方案3】:

将此代码放入 onPreExecute() 中,如下所示

@Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        // product with this pid found
        // Edit Text
        txtName = (TextView) findViewById(R.id.app_name);
        txtVersion = (TextView) findViewById(R.id.app_version);
        txtDesc = (TextView) findViewById(R.id.desc_app);
        pDialog.show();
    }

【讨论】:

    猜你喜欢
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 1970-01-01
    • 2011-11-29
    • 2014-05-15
    • 1970-01-01
    相关资源
    最近更新 更多