【问题标题】:Attempting to follow basic How to connect Android with PHP, MySQL tutorial: application crashes - cannot import android.os.StrictMode尝试遵循基本的 How to connect Android with PHP, MySQL 教程:应用程序崩溃 - 无法导入 android.os.StrictMode
【发布时间】:2013-03-17 18:21:31
【问题描述】:

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

但是,几乎所有尝试本教程的人(从 cmets 来看)都遇到了强制关闭问题,因为该应用程序仅设计为在 API 级别 8 或更早版本上运行。

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

// 这部分仅用于确定工作代码的放置位置

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

// 注意 * 在 EditProductActivity.java 的导入部分插入下面的行 // 导入 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();

    }

}
}

【问题讨论】:

    标签: java android eclipse multithreading android-strictmode


    【解决方案1】:
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
    .permitAll().build();
    StrictMode.setThreadPolicy(policy);
    

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

    更新:

    您的应用没有很好地指定。看看这个

    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 更新。你不应该混合它。

    如果你想更新 UI,AsyncTask 提供了适当的方法来实现它:

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

    因此,如果您想使用有关自动调用 onProgressUpdate() 方法并从其更新 UI 的后台任务调用 publishProgress(&lt;data&gt;) 方法的进度的一些信息来更新您的 UI。

    在您的情况下,您不应该在 doInBackground() 方法中执行 UI 元素的初始化。

    我建议你这样做:

    1. onCreate() 方法中初始化您的小部件。
    2. 当您想使用从以下位置检索到的数据更新它们时 doInBackground() 方法,调用 publishProgress() 调用 onProgressUpdate() 方法,这里执行更新

    示例如下:

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

    基于上面提到的事情我猜你需要阅读 AsyncTask 教程:

    【讨论】:

    • 如果我删除:StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .permitAll().build(); StrictMode.setThreadPolicy(policy);我收到以下错误:docs.google.com/document/d/… 这是本教程中大多数人遇到的原始问题 - 他们建议添加: StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() .permitAll().build( ); StrictMode.setThreadPolicy(policy); ...纠正问题。
    • @user2161499 你正在使用 AsynTask 你不需要 StrickMode...仔细阅读我的答案,你的应用程序设计得很混乱。
    • 有什么方法可以告诉我如何做到这一点?我对此很陌生(我只是想完成一个 MYSQL 教程并在我的应用程序中获取数据 - 一直跳到解决线程问题上有点超出我的理解水平,我真的只需要让这个应用程序将数据传递到我的服务器[我真的没想到这样做会这么复杂])
    • @user2161499 看看我最后的答案是链接。
    • 其他用户似乎认为这不是 ASyncTask 的问题,而是 URL 不正确的问题 - 你同意吗? (我感觉这很简单)stackoverflow.com/questions/15464958/…
    【解决方案2】:

    只要确保您的服务器和安卓设备都连接到同一个 wifi 连接,将 ip 地址更改为您的服务器地址,例如:将其更改为 192.168.1.102(无论您的服务器上显示什么

    代码运行良好,我试过了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 2012-01-19
      • 1970-01-01
      相关资源
      最近更新 更多