尝试按照基本如何连接Android与PHP,MySQL教程:应用程序崩溃 - 无法导入android.os.StrictMode

时间:2013-03-17 18:21:31

标签: java android eclipse multithreading android-strictmode

好的 - 我正在使用以下教程:“如何将Android与PHP,MySQL连接”

然而,几乎所有尝试本教程的人(从评论中判断)都有强制关闭问题,因为应用程序只能在API级别8或更早版本上运行。

有几个用户为此开发了一个修复程序,包括在EditProductActivity.java文件中添加以下代码行

//此部分仅用于标识工作代码的放置位置

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_product);

// NB *在EditProductActivity.java的import部分插入以下行 // import android.os.StrictMode;

//现在代码可以避免NetworkOnMainThreadException错误

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);

但是我在我的logcat中收到消息,说明StrictMode无法解析,并且StrictMode无法解析为某种类型。我对此进行了一些研究,StrictMode包含在API级别8及更高级别中。考虑到这一点,我已将AndroidManifest.xml中的API级别提升为:

 <uses-sdk android:minSdkVersion="9"
          android:targetSdkVersion="9"/>

然后清理了我的项目 - 但是我仍然得到StrictMode无法解析为类型错误。

logcat的:

    03-17 14:06:57.924: D/AndroidRuntime(18472): Shutting down VM
    03-17 14:06:57.924: W/dalvikvm(18472): threadid=1: thread exiting with uncaught exception (group=0x41604930)
    03-17 14:06:57.924: E/AndroidRuntime(18472): FATAL EXCEPTION: main
    03-17 14:06:57.924: E/AndroidRuntime(18472): java.lang.Error: Unresolved compilation problems: 
    03-17 14:06:57.924: E/AndroidRuntime(18472):    The import android.os.StrictMode cannot be resolved
   03-17 14:06:57.924: E/AndroidRuntime(18472):     StrictMode cannot be resolved to a type
    03-17 14:06:57.924: E/AndroidRuntime(18472):    StrictMode cannot be resolved to a type
    03-17 14:06:57.924: E/AndroidRuntime(18472):    StrictMode cannot be resolved
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at com.example.androidhive.NewProductActivity.<init>(NewProductActivity.java:10)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at java.lang.Class.newInstanceImpl(Native Method)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at java.lang.Class.newInstance(Class.java:1319)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.os.Handler.dispatchMessage(Handler.java:99)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.os.Looper.loop(Looper.java:137)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at android.app.ActivityThread.main(ActivityThread.java:5039)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at java.lang.reflect.Method.invokeNative(Native Method)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at java.lang.reflect.Method.invoke(Method.java:511)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    03-17 14:06:57.924: E/AndroidRuntime(18472):    at dalvik.system.NativeStart.main(Native Method)

JAVA:

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.StrictMode;

 public class EditProductActivity extends Activity {

EditText txtName;
EditText txtPrice;
EditText txtDesc;
EditText txtCreatedAt;
Button btnSave;
Button btnDelete;

String pid;

// Progress Dialog
private ProgressDialog pDialog;

// JSON parser class
JSONParser jsonParser = new JSONParser();

// single product url
private static final String url_product_detials =  "http://linkingmanager.zxq.net/get_product_details.php";

// url to update product
private static final String url_update_product = "http://linkingmanager.zxq.net/update_product.php";

// url to delete product
private static final String url_delete_product = "http://linkingmanager.zxq.net/delete_product.php";

// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCT = "product";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";
private static final String TAG_PRICE = "price";
private static final String TAG_DESCRIPTION = "description";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit_product);

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
    .permitAll().build();
    StrictMode.setThreadPolicy(policy);

    // save button
    btnSave = (Button) findViewById(R.id.btnSave);
    btnDelete = (Button) findViewById(R.id.btnDelete);

    // getting product details from intent
    Intent i = getIntent();

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

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

    // save button click event
    btnSave.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // starting background task to update product
            new SaveProductDetails().execute();
        }
    });

    // Delete button click event
    btnDelete.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // deleting product in background thread
            new DeleteProduct().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(EditProductActivity.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_detials, "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_PRODUCT); // JSON Array

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

                        // product with this pid found
                        // Edit Text
                        txtName = (EditText) findViewById(R.id.inputName);
                        txtPrice = (EditText) findViewById(R.id.inputPrice);
                        txtDesc = (EditText)  findViewById(R.id.inputDesc);

                        // display product data in EditText
                          txtName.setText(product.getString(TAG_NAME));
                        txtPrice.setText(product.getString(TAG_PRICE));
                        txtDesc.setText(product.getString(TAG_DESCRIPTION));

                    }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();
    }
}

/**
 * Background Async Task to  Save product Details
 * */
class SaveProductDetails extends AsyncTask<String, String, String> {

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

    /**
     * Saving product
     * */
    protected String doInBackground(String... args) {

        // getting updated data from EditTexts
        String name = txtName.getText().toString();
        String price = txtPrice.getText().toString();
        String description = txtDesc.getText().toString();

        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair(TAG_PID, pid));
        params.add(new BasicNameValuePair(TAG_NAME, name));
        params.add(new BasicNameValuePair(TAG_PRICE, price));
        params.add(new BasicNameValuePair(TAG_DESCRIPTION, description));

        // sending modified data through http request
        // Notice that update product url accepts POST method
        JSONObject json = jsonParser.makeHttpRequest(url_update_product,
                "POST", params);

        // check json success tag
        try {
            int success = json.getInt(TAG_SUCCESS);

            if (success == 1) {
                // successfully updated
                Intent i = getIntent();
                // send result code 100 to notify about product update
                setResult(100, i);
                finish();
            } else {
                // failed to update product
            }
        } 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 product uupdated
        pDialog.dismiss();
    }
}

/*****************************************************************
 * Background Async Task to Delete Product
 * */
class DeleteProduct extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(EditProductActivity.this);
        pDialog.setMessage("Deleting Product...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    /**
     * Deleting product
     * */
    protected String doInBackground(String... args) {

        // 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
            JSONObject json = jsonParser.makeHttpRequest(
                    url_delete_product, "POST", params);

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

            // json success tag
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                // product successfully deleted
                // notify previous activity by sending code 100
                Intent i = getIntent();
                // send result code 100 to notify about product deletion
                setResult(100, i);
                finish();
            }
        } 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 product deleted
        pDialog.dismiss();

    }

}
}

2 个答案:

答案 0 :(得分:2)

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);

由于您使用AsyncTask,因此无需设置ThreadPolicy。请不要忘记StrictMode从2.3版本开始可用。

更新

您的应用未被很好地指定。看看这个

protected String doInBackground(String... params) {

        runOnUiThread(new Runnable() { 
           ...
           txtName = (EditText) findViewById(R.id.inputName);
           txtPrice = (EditText) findViewById(R.id.inputPrice);
           txtDesc = (EditText)  findViewById(R.id.inputDesc);

           // display product data in EditText
           txtName.setText(product.getString(TAG_NAME));
           txtPrice.setText(product.getString(TAG_PRICE));
           txtDesc.setText(product.getString(TAG_DESCRIPTION));
           ...
        }
}

你为什么这样做? doInBackground()直接设计用于执行后台操作,也已在后台线程上运行,您不应该从中执行UI更新。你不应该混合它。

如果您想更新用户界面,AsyncTask提供了实现它的正确方法:

  • onPreExecute()
  • onProgressUpdate()
  • onPostExecute()

因此,如果您想要使用自动调用publishProgress(<data>)方法及其更新UI的后台任务调用onProgressUpdate()方法的进度更新您的UI。

在您的情况下,您正在使用UI方法初始化doInBackground()元素,而不应该这样做。

我建议你这样做:

  1. 使用onCreate()方法初始化您的小部件。
  2. 如果要使用从中检索的数据更新它们 doInBackground()方法,调用publishProgress()调用 onProgressUpdate()方法,此处执行更新
  3. 以下是示例:

    @Override
    protected void onProgressUpdate(String... params) {
       txtName.setText(<value>);
       ...
    }
    

    根据上面提到的事情,我猜你需要阅读AsyncTask教程:

答案 1 :(得分:0)

只需确保您的服务器和Android设备都连接到相同的wifi连接,将IP地址更改为您的服务器地址,例如:将其更改为192.168.1.102(无论您的服务器上显示什么

代码运行良好,我尝试过它