androidhandler能不能传递较多数据
答案:5 悬赏:60
解决时间 2021-11-22 02:02
- 提问者网友:不懂我就别说我变
- 2021-11-21 04:40
androidhandler能不能传递较多数据
最佳答案
- 二级知识专家网友:如果这是命
- 2021-11-21 05:41
这个是没问题的:
handler主要接受子线程发送的数据, 并用此数据配合主线程更新UI。
解释:当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 要是点击一个 Button ,Android会分发事件到Button上,来响应操作。
如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,不能把这些操作放在主线程中,如果放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。 这个时候需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。 这个时候,Handler就出现了。来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
handler主要接受子线程发送的数据, 并用此数据配合主线程更新UI。
解释:当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 要是点击一个 Button ,Android会分发事件到Button上,来响应操作。
如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,不能把这些操作放在主线程中,如果放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。 这个时候需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。 这个时候,Handler就出现了。来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
全部回答
- 1楼网友:一起来看看吧
- 2021-11-21 09:36
第一种思想是推荐使用的,任何函数在调用的时候,涉及到传递参数,都会降低效率。根据message的源码setdata(bundle data)它的注释:
sets a bundle of arbitrary data values. use arg1 and arg1 members as a lower cost way to send a few simple integer values, if you can.意思是说,尽量使用arg1和arg2传递整型数据,降低开销(lower cost)。因此你的第二种想法完全就是多此一举,因为handler的设计思想就是通知主线程更新数据,用最小的开销去通知。
- 2楼网友:单身小柠`猫♡
- 2021-11-21 08:58
看你数据量有多大。只是种类多的话把要传的数据封装成一个类,添加到Message的obj里面就行;如果数据量占用空间大的话直接传递可能会影响处理速度,这时可以考虑传递文件
- 3楼网友:陪衬角色
- 2021-11-21 08:13
看你数据量有多大。只是种类多的话把要传的数据封装成一个类,添加到Message的obj里面就行;如果数据量占用空间大的话直接传递可能会影响处理速度,这时可以考虑传递文件
- 4楼网友:茫然不知崩溃
- 2021-11-21 06:45
用HandlerThread的looper来构造一个handler,然后该handler自己获得消息,并传递数据,然后又自己处理消息,当然这是在另一个线程中完成的。
消息结构中传递简单的整型可以采用它的参数arg1和arg2,或者传递一些小的其它数据,可以用它的object,该object可以是任意的对象。当需要传送比较大的数据是,可以使用消息的setData方法,该方法需要传递一个Bundle的参数。Bundle中存放的是键值对的map,只是它的键值类型和数据类型比较固定而已。
程序主要代码和注释如下:
MainActivity.java:
复制代码
代码如下:
package com.example.handler4;
import android.app.Activity;
import android.os.Bundle;
import
android.os.Handler;
import android.os.HandlerThread;
import
android.os.Looper;
import android.os.Message;
import
android.view.Menu;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("activity_ID---->"+Thread.currentThread().getId());
//新建一个HanderThread对象,该对象实现了用Looper来处理消息队列的功能
HandlerThread
handler_thread = new HandlerThread("handler_thread");
handler_thread.start();
//MyHandler类是自己继承的一个类,这里采用hand_thread的Looper来初始化它
MyHandler
my_handler = new MyHandler(handler_thread.getLooper());
//获得一个消息msg
Message msg = my_handler.obtainMessage();
//采用Bundle保存数据,Bundle中存放的是键值对的map,只是它的键值类型和数据类型比较固定而已
Bundle b = new
Bundle();
b.putString("whether", "晴天");
b.putInt("temperature", 34);
msg.setData(b);
//将msg发送到自己的handler中,这里指的是my_handler,调用该handler的HandleMessage方法来处理该mug
msg.sendToTarget();
}
class MyHandler extends Handler
{
//空的构造函数
public MyHandler()
{}
//以Looper类型参数传递的函数,Looper为消息泵,不断循环的从消息队列中得到消息并处理,因此
//每个消息队列都有一个Looper,因为Looper是已经封装好了的消息队列和消息循环的类
public
MyHandler(Looper looper)
{
//调用父类的构造函数
super(looper);
}
@Override
public void
handleMessage(Message msg) {
// TODO Auto-generated method
stub
System.out.println("Handler_ID---->"+Thread.currentThread().getId());
System.out.println("Handler_Name---->"+Thread.currentThread().getId());
//将消息中的bundle数据取出来
Bundle b = msg.getData();
String whether = b.getString("whether");
int temperature =
b.getInt("temperature");
System.out.println("whether= "+whether+"
,temperature= "+temperature);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return
true;
}
}
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯