• ANR和消息机制


    anr产生的原理&如何避免

    ANR : application not response 应用程序无响应

    ANR产生的原因 :  

    主线程需要做很多重要的事情,如响应点击事件,更新ui

    如果在主线程里边阻塞过久的时间,应用程序就会无响应

    为了避免出现ANR,所有耗时的操作都应该放在子线程里边执行

    public void watch(View view) {

    final String path = this.et_path.getText().toString().trim();

    if (TextUtils.isEmpty(path)) {

    Toast.makeText(this, "路径不能为空", 0).show();

    } else {

    new Thread() {

    @Override

    public void run() {

    try {

    URL url = new URL(path);

    HttpURLConnection connection = (HttpURLConnection) url

    .openConnection();

    // 设置请求方式

    connection.setRequestMethod("GET");

    // 设置超时时间

    connection.setConnectTimeout(10000);

    // connection.setRequestProperty(field, newValue)

    int code = connection.getResponseCode();

    if (code == 200) {

    InputStream is = connection.getInputStream();

    Bitmap bitmap = BitmapFactory.decodeStream(is);

    iv_beauty.setImageBitmap(bitmap);

    } else {

    Toast.makeText(MainActivity.this, "获取图片失败", 0).show();

    }

    } catch (Exception e) {

    e.printStackTrace();

    Toast.makeText(MainActivity.this, "读取图片失败", 0).show();

    }

    }

    }.start();

    }

    }

    此时程序有抛出了异常:

    android.view.ViewRootImpl$CalledFromWrongThreadException: 

    Only the original thread that created a view hierarchy can touch its views.

    说白了,谁创建的view对象,谁才能动它

    在安卓系统中,只有主线程才能修改veiw对象

    内部实现:更改界面的时候做一个检查,检查这个更新操作是否在主线程的代码执行的,

              如果是,没有任何问题

              不过不是,立刻抛出一个运行时异常 ViewRootImpl$CalledFromWrongThreadException

    通过消息机制来解决这个问题

    android消息机制入门

    public class MainActivity extends Activity {

    protected static final int UPDATE_UI = 1;

    protected static final int ERROR = 2;

    private ImageView iv_beauty;

    private EditText et_path;

     // 主线程创建消息处理器

    Handler handler = new Handler() {

    @Override

    public void handleMessage(Message msg) {

    if(msg.what == UPDATE_UI) {

    iv_beauty.setImageBitmap((Bitmap)msg.obj);

    } else {

    Toast.makeText(getApplicationContext(), "图片获取失败!", 0).show();

    }

    }

    };

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    this.iv_beauty = (ImageView) this.findViewById(R.id.iv_beauty);

    this.et_path = (EditText) this.findViewById(R.id.et_path);

    }

    public void watch(View view) {

    final String path = this.et_path.getText().toString().trim();

    if (TextUtils.isEmpty(path)) {

    Toast.makeText(this, "路径不能为空", 0).show();

    } else {

    new Thread() {

    @Override

    public void run() {

    try {

    URL url = new URL(path);

    HttpURLConnection connection = (HttpURLConnection) url

    .openConnection();

    // 设置请求方式

    connection.setRequestMethod("GET");

    // 设置超时时间

    connection.setConnectTimeout(10000);

    // connection.setRequestProperty(field, newValue)

    int code = connection.getResponseCode();

    if (code == 200) {

    InputStream is = connection.getInputStream();

    Bitmap bitmap = BitmapFactory.decodeStream(is);

     // 告诉主线程一个消息,帮我更新ui,内容:bitmap

     Message msg = new Message();

    msg.what = UPDATE_UI;

    msg.obj = bitmap;

    handler.sendMessage(msg);

    } else {

     Message msg = new Message();

    msg.what = ERROR;

    handler.sendMessage(msg);

    }

    } catch (Exception e) {

    e.printStackTrace();

     Message msg = new Message();

    msg.what = ERROR;

    handler.sendMessage(msg);

    }

    }

    }.start();

    }

    }

    }

    提交数据到服务器

    1.布局文件

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        xmlns:tools="http://schemas.android.com/tools"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical"

        tools:context=".MainActivity" >

        <EditText

            android:id="@+id/et_username"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:hint="请输入用户名" />

        <EditText

            android:id="@+id/et_password"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:hint="请输入密码"

            android:inputType="textPassword" />

        <Button

    android:onClick="get"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="get请求登录" />

        

        <Button

    android:onClick="post"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="post请求登录" />

        

        <Button

    android:onClick="clientGet"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="client get请求登录" />

        

        <Button

    android:onClick="clientPost"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="client post请求登录" />

    </LinearLayout>

    2.Activity

    public class MainActivity extends Activity {

    private EditText et_userName;

    private EditText et_password;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    this.et_userName = (EditText) this.findViewById(R.id.et_username);

    this.et_password = (EditText) this.findViewById(R.id.et_password);

    }

    public void get(View view) {

    final String userName = this.et_userName.getText().toString().trim();

    final String password = this.et_password.getText().toString().trim();

    new Thread() {

    public void run() {

    final String result = LoginService.loginByGet(userName,

    password);

    if (result != null) {

    /*

     * Runs the specified action on the UI thread. If the

     * current thread is the UI thread, then the action is

     * executed immediately. If the current thread is not the UI

     * thread, the action is posted to the event queue of the UI

     * thread.

     */

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, result, 0).show();

    }

    });

    } else {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, "请求失败。。。。", 0)

    .show();

    }

    });

    }

    };

    }.start();

    }

    public void post(View view) {

    final String userName = this.et_userName.getText().toString().trim();

    final String password = this.et_password.getText().toString().trim();

    new Thread() {

    public void run() {

    final String result = LoginService.loginByPost(userName,

    password);

    if (result != null) {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, result, 0).show();

    }

    });

    } else {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, "请求失败。。。。", 0)

    .show();

    }

    });

    }

    };

    }.start();

    }

    public void clientGet(View view) {

    final String userName = this.et_userName.getText().toString().trim();

    final String password = this.et_password.getText().toString().trim();

    new Thread() {

    public void run() {

    final String result = LoginService.loginByClientGet(userName,

    password);

    if (result != null) {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, result, 0).show();

    }

    });

    } else {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, "请求失败。。。。", 0)

    .show();

    }

    });

    }

    };

    }.start();

    }

    public void clientPost(View view) {

    final String userName = this.et_userName.getText().toString().trim();

    final String password = this.et_password.getText().toString().trim();

    new Thread() {

    public void run() {

    final String result = LoginService.loginByClientPost(userName,

    password);

    if (result != null) {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, result, 0).show();

    }

    });

    } else {

    runOnUiThread(new Runnable() {

    @Override

    public void run() {

    Toast.makeText(MainActivity.this, "请求失败。。。。", 0)

    .show();

    }

    });

    }

    };

    }.start();

    }

    }

    3.业务类

    public class LoginService {

    /*

     * 采用get方式请求

     */

    public static String loginByGet(String userName, String password) {

    try {

    String path = "http://110.65.99.66:8080/androidserver/WebServlet?userName="

    + URLEncoder.encode(userName, "UTF-8")

    + "&password="

    + URLEncoder.encode(password, "UTF-8");

    URL url = new URL(path);

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setRequestMethod("GET");

    conn.setReadTimeout(5000);

    int code = conn.getResponseCode();

    if (code == 200) {

    InputStream is = conn.getInputStream();

    String result = StreamTool.readInputStream(is);

    is.close();

    return result;

    } else {

    return null;

    }

    } catch (Exception e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    return null;

    }

    /*

     * 采用post方式

     */

    public static String loginByPost(String userName, String password) {

    String path = "http://110.65.99.66:8080/androidserver/WebServlet";

    try {

    URL url = new URL(path);

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setRequestMethod("POST");

    conn.setReadTimeout(5000);

    String params = "userName=" + URLEncoder.encode(userName, "UTF-8")

    + "&password=" + URLEncoder.encode(password, "UTF-8");

    // 设置请求

    /**

     * application/x-www-form-urlencoded 普通表单数据提交方式 multipart/form-data

     * 文件上传 text/plain 原始文本数据

     */

    conn.setRequestProperty("content-type",

    "application/x-www-form-urlencoded");

    conn.setRequestProperty("content-length", params.length() + "");

    conn.setDoOutput(true);

    OutputStream outputStream = conn.getOutputStream();

    outputStream.write(params.getBytes());

    int code = conn.getResponseCode();

    if (code == 200) {

    InputStream is = conn.getInputStream();

    String result = StreamTool.readInputStream(is);

    is.close();

    return result;

    } else {

    return null;

    }

    } catch (Exception e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    return null;

    }

    /*

     * 采用HttpGet方式

     */

    public static String loginByClientGet(String userName, String password) {

    try {

    // 1.打开浏览器

    HttpClient client = new DefaultHttpClient();

    // 2.输入网址

    String path = "http://110.65.99.66:8080/androidserver/WebServlet?userName="

    + userName + "&password=" + password;

    HttpGet httpGet = new HttpGet(path);

    // 3.敲回车

    HttpResponse response = client.execute(httpGet);

    int code = response.getStatusLine().getStatusCode();

    if (code == 200) {

    InputStream is = response.getEntity().getContent();

    String result = StreamTool.readInputStream(is);

    is.close();

    return result;

    } else {

    return null;

    }

    } catch (Exception e) {

    // TODO: handle exception

    }

    return null;

    }

    /*

     * 采用HttpPost方式

     */

    public static String loginByClientPost(String userName, String password) {

    try {

    // 1.打开浏览器

    HttpClient client = new DefaultHttpClient();

    // 2.输入网址

    String path = "http://110.65.99.66:8080/androidserver/WebServlet";

    HttpPost httpPost = new HttpPost(path);

    // 3.设置参数

    ArrayList<NameValuePair> parameters = new ArrayList<NameValuePair>();

    parameters.add(new BasicNameValuePair("userName", userName));

    parameters.add(new BasicNameValuePair("password", password));

    httpPost.setEntity(new UrlEncodedFormEntity(parameters, "utf-8"));

    // 4.敲回车

    HttpResponse response = client.execute(httpPost);

    int code = response.getStatusLine().getStatusCode();

    if (code == 200) {

    InputStream is = response.getEntity().getContent();

    String result = StreamTool.readInputStream(is);

    is.close();

    return result;

    } else {

    return null;

    }

    } catch (Exception e) {

    // TODO: handle exception

    }

    return null;

    }

    }

  • 相关阅读:
    几何变换
    图片移动、旋转、resize、
    load、display、save
    java基础—java三大集合ArrayList、HashSet、HashMap
    java基础—修饰符、抽象类、接口
    java基础——转义字符
    java基础—String类型常用api
    Python中 sys.argv[]的用法
    Java—this关键字
    在CMD中运行Python文件
  • 原文地址:https://www.cnblogs.com/freenovo/p/4469831.html
Copyright © 2020-2023  润新知