android给子线程传值

本文详细介绍了如何在Android应用中从主线程(UI线程)向非UI线程(子线程)发送消息,并通过自定义线程和消息处理机制实现消息传递。同时,阐述了如何在非UI线程中获取并处理消息,以及如何将从网络获取的数据正确地展示在UI界面上。通过实例代码演示了消息传递的完整过程,包括创建线程、消息循环、消息处理及UI更新等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载http://www.cnblogs.com/jackhuclan/archive/2013/07/10/3182084.html

 

从主线程发送消息到子线程(准确地说应该是非UI线程)

package com.zhuozhuo;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

 

public class LooperThreadActivity extends Activity{

    /** Called when the activity is first created. */

   

    private final int MSG_HELLO = 0;

    private Handler mHandler;

   

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        new CustomThread().start();//新建并启动CustomThread实例

       

        findViewById(R.id.send_btn).setOnClickListener(new OnClickListener() {

           

            @Override

            public void onClick(View v) {//点击界面时发送消息

                String str = "hello";

                Log.d("Test", "MainThread is ready to send msg:" + str);

                mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();//发送消息到CustomThread实例

               

            }

        });

       

    }

   

   

   

   

   

    class CustomThread extends Thread {

        @Override

        public void run() {

            //建立消息循环的步骤

            Looper.prepare();//1、初始化Looper

            mHandler = new Handler(){//2、绑定handler到CustomThread实例的Looper对象

                public void handleMessage (Message msg) {//3、定义处理消息的方法

                    switch(msg.what) {

                    case MSG_HELLO:

                        Log.d("Test", "CustomThread receive msg:" + (String) msg.obj);

                    }

                }

            };

            Looper.loop();//4、启动消息循环

        }

    }

}

 

 

 

从非UI线程传递消息到UI线程(界面主线程),因为主界面已经有MessageQueue,所以可以直接获取消息处理消息。而上面由主线程向非UI线程中处理消息的时候,非UI线程需要先添加消息队列,然后处理消息循环。

 

public class ThreadHandlerActivity extends Activity {
    /** Called when the activity is first created. */
   
    private static final int MSG_SUCCESS = 0;//获取图片成功的标识
    private static final int MSG_FAILURE = 1;//获取图片失败的标识
   
    private ImageView mImageView;
    private Button mButton;
   
    private Thread mThread;
   
    private Handler mHandler = new Handler() {
        public void handleMessage (Message msg) {//此方法在ui线程运行
            switch(msg.what) {
            case MSG_SUCCESS:
                mImageView.setImageBitmap((Bitmap) msg.obj);//imageview显示从网络获取到的logo
                Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_success), Toast.LENGTH_LONG).show();
                break;

            case MSG_FAILURE:
                Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_failure), Toast.LENGTH_LONG).show();
                break;
            }
        }
    };
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mImageView= (ImageView) findViewById(R.id.imageView);//显示图片的ImageView
        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new OnClickListener() {
           
            @Override
            public void onClick(View v) {
                if(mThread == null) {
                    mThread = new Thread(runnable);
                    mThread.start();//线程启动
                }
                else {
                    Toast.makeText(getApplication(), getApplication().getString(R.string.thread_started), Toast.LENGTH_LONG).show();
                }
            }
        });
    }
   
    Runnable runnable = new Runnable() {
       
        @Override
        public void run() {//run()在新的线程中运行
            HttpClient hc = new DefaultHttpClient();
            HttpGet hg = new HttpGet("http://csdnimg.cn/www/images/csdnindex_logo.gif");//获取csdn的logo
            final Bitmap bm;
            try {
                HttpResponse hr = hc.execute(hg);
                bm = BitmapFactory.decodeStream(hr.getEntity().getContent());
            } catch (Exception e) {
                mHandler.obtainMessage(MSG_FAILURE).sendToTarget();//获取图片失败
                return;
            }
            mHandler.obtainMessage(MSG_SUCCESS,bm).sendToTarget();//获取图片成功,向ui线程发送MSG_SUCCESS标识和bitmap对象

//            mImageView.setImageBitmap(bm); //出错!不能在非ui线程操作ui元素

//            mImageView.post(new Runnable() {//另外一种更简洁的发送消息给ui线程的方法。
//               
//                @Override
//                public void run() {//run()方法会在ui线程执行
//                    mImageView.setImageBitmap(bm);
//                }
//            });
        }
    };

 

Android 应用中,如果需要与 WebView 中加载的网页进行交互,尤其是与 JavaScript 进行双向通信,可以使用 Android 提供的 `WebView` 和 `addJavascriptInterface` 方法实现 Java 与 JavaScript 的交互。 --- ### 示例:Android 与 JavaScript 交互 #### 1. 布局文件 `activity_main.xml` ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ``` #### 2. Java 代码 `MainActivity.java` ```java package com.example.androidjs; import android.os.Bundle; import android.webkit.JavascriptInterface; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webview); WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); // 启用 JavaScript // 添加 JavaScript 接口 webView.addJavascriptInterface(new WebAppInterface(), "Android"); // 加载本地 HTML 文件(放在 assets 目录下) webView.loadUrl("file:///android_asset/index.html"); } // 定义一个类,用于暴露给 JS 调用 public class WebAppInterface { @JavascriptInterface public void showToast(String message) { Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show(); } @JavascriptInterface public String getMessageFromAndroid() { return "Hello from Android!"; } } } ``` #### 3. HTML 文件 `index.html`(放在 `assets` 目录下) ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Android JS Interaction</title> <script type="text/javascript"> function callAndroidToast() { Android.showToast("Hello from JavaScript!"); } function getAndroidMessage() { var message = Android.getMessageFromAndroid(); document.getElementById("output").innerText = message; } </script> </head> <body> <h1>Android - JavaScript 交互示例</h1> <button onclick="callAndroidToast()">点击调用 Android 的 Toast</button> <br><br> <button onclick="getAndroidMessage()">获取 Android 的消息</button> <p id="output"></p> </body> </html> ``` --- ### 代码解释 1. **启用 JavaScript**: - 在 `WebView` 中启用 JavaScript 是交互的前提。 - 使用 `webSettings.setJavaScriptEnabled(true);` 2. **添加 JavaScript 接口**: - 使用 `addJavascriptInterface()` 方法将 Java 对象暴露给 JavaScript。 - 本例中将 `WebAppInterface` 类暴露为 `Android` 对象,JavaScript 可以通过 `Android.showToast()` 和 `Android.getMessageFromAndroid()` 调用。 3. **JavaScript 调用 Java 方法**: - 在 HTML 文件中,JavaScript 可以直接调用 `Android.showToast("message")` 来触发 Android 的 `Toast`。 4. **Java 调用 JavaScript 方法**: - 如果你需要从 Android 主动调用 JavaScript 方法,可以使用 `webView.evaluateJavascript()` 方法: ```java webView.evaluateJavascript("javascript:document.getElementById('output').innerText = 'Updated from Android'", null); ``` --- ### 注意事项 - **安全问题**:从 Android 4.2(API 17)开始,`@JavascriptInterface` 注解是必须的,否则 JS 无法访问 Java 方法。 - **线程问题**:JS 调用 Java 方法是在主线程中执行的,不能执行耗时操作。 - **权限问题**:如果加载的是网络资源,确保在 `AndroidManifest.xml` 中添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值