当前位置:首页 » 网页前端 » 多线程与前端ui交互
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

多线程与前端ui交互

发布时间: 2022-09-18 18:34:12

A. 在多线程中,子线程更新主线程ui有哪些方法及注意点

Android

UI多线程Androidthread工作

在一个Android 程序开始运行的时候,会单独启动一个Process。默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process。

一个Android 程序默认情况下也只有一个Process,但一个Process下却可以有许多个Thread。在这么多Thread当中,有一个Thread,我们称之为UI Thread。UI Thread在Android程序运行的时候就被创建,是一个Process当中的主线程Main Thread,主要是负责控制UI界面的显示、更新和控件交互。在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UI Thread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。

那么,UI Thread如何和其他Thread一起工作呢?常用方法是:

诞生一个主线程的Handler物件,当做Listener去让子线程能将讯息Push到主线程的Message Quene里,以便触发主线程的handlerMessage()函数,让主线程知道子线程的状态,并在主线程更新UI。

例如,在子线程的状态发生变化时,我们需要更新UI。如果在子线程中直接更新UI,通常会抛出下面的异常:11-07 13:33:04.393: ERROR/JavaBinder(1029):android.view.ViewRoot$:Only the original thread that created a view hierarchy can touch its views.

意思是,无法在子线程中更新UI。为此,我们需要通过Handler物件,通知主线程Ui Thread来更新界面。

如下,首先创建一个Handler,来监听Message的事件:

private final int UPDATE_UI = 1;private Handler mHandler = new MainHandler();private class MainHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE_UI: {Log.i("TTSDeamon", "UPDATE_UI");showTextView.setText(editText.getText().toString());ShowAnimation();break;}default:break;}}}

或者

private Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case UPDATE_UI: {Log.i("TTSDeamon", "UPDATE_UI");showTextView.setText(editText.getText().toString());ShowAnimation();break;}default:break;}}}

当子线程的状态发生变化,则在子线程中发出Message,通知更新UI。

mHandler.sendEmptyMessageDelayed(UPDATE_UI, 0);

在我们的程序中,很多Callback方法有时候并不是运行在主线程当中的,所以如果在Callback方法中更新UI失败,也可以采用上面的方法。

B. Android 怎么启动一个工作线程及线程如何与UI线程交互

通过Handler通知UI线程,更新状态信息,部分代码,请参阅下面:

privatevoidSynTask(){
newThread(){
@Override
publicvoidrun(){
if(IsHaveInternet()){//联网
DowloadData();//下载数据
//通知UI
Messagemsg=newMessage();
msg.what=mDonlandEnd;
handler.sendMessage(msg);
}
}
}.start();
}

UI主线程,怎么通过handler接手工作线程的信息呢:

Handlerhandler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
casemmDonlandEnd:
ShowToast(GetString(R.string.DonlandEnd));
break;
default:
break;
}
}
};

C. Android开发中多线程与UI更新

直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,如下错误:android.view.ViewRoot$: Only the original thread that created a view hierarchy can touch its views.翻译过来就是:只有创建这个控件的线程才能去更新该控件的内容。

所有的UI线程要去负责View的创建并且维护它,例如更新冒个TextView的显示,都必须在主线程中去做,我们不能直接在UI线程中去创建子线程,要利用消息机制:handler,如下就是handler的简单工作原理图:

既然android给我们提供了Handler机制来解决这样的问题,请看如下代码:

public class HandlerTestActivity extends Activity { private TextView tv; private static final int UPDATE = 0; private Handler handler = new Handler() { @Overridepublic void handleMessage(Message msg) { // TODO 接收消息并且去更新UI线程上的控件内容if (msg.what == UPDATE) { // Bundle b = msg.getData();// tv.setText(b.getString("num")); tv.setText(String.valueOf(msg.obj)); } super.handleMessage(msg); } }; /** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv = (TextView) findViewById(R.id.tv); new Thread() { @Overridepublic void run() { // TODO 子线程中通过handler发送消息给handler接收,由handler去更新TextView的值try { for (int i = 0; i < 100; i++) { Thread.sleep(500); Message msg = new Message(); msg.what = UPDATE; // Bundle b = new Bundle();// b.putString("num", "更新后的值:" + i);// msg.setData(b); msg.obj = "更新后的值:" + i; handler.sendMessage(msg); } } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); }}

我们就通过Handler机制来处理了子线程去更新UI线程控件问题,Andrid开发中要经常用到这种机制。

D. 前端交互和UI设计有什么区别

据了解,并没有前端交互,只有交互设计,这里就来说说交互设计岗位和Ui设计
交互设计:偏重于产品的用户交互行为设计,更多的是在产品最早期完成;而交互设计注重的是用户体验的操作部分;比如在文本框输入文字的时候,你敲击键盘,文本框出现候选文字,这个部分就是交互
Ui设计:偏重于视觉层面,轻用户交互行为设计,注重的是从视觉吸引用户以及引导用户操作。同样的例子,敲击键盘的时候,把常用文字用红色标注出来,这种就属于Ui设计中需要完成的事情
而无论是交互设计、Ui设计,都是殊途同归,最终都是需要去把握用户心理,去创造

E. 如何用C#编写多线程的与窗体交互的程序

C#中的UI元素是主线程创建的,也只能通过创建它们的主线程进行修改,这是因为UI元素本身不是线程安全的,多线程操作会发生不可预料的错误。因此,默认情况下,尝试从其他线程操作UI元素会引发异常,虽然你可以通过下面的代码强制允许UI元素的跨线程操作:

=false;


但是,这样做是不推荐的。一般对于UI元素的跨线程操作推荐使用

Form.Invoke(Delegatemethod);
Form.Invoke(Delegatemethod,paramsobject[]args);

Invoke方法可以由任何线程调用,但只会在创建Form的主线程上执行相应的Delegate。


一段最简示例如下:

privatevoidbutton1_Click(objectsender,EventArgse)
{
newSystem.Threading.Thread(ThreadAction).Start();//启动线程
}
privatevoidThreadAction()
{
this.Invoke(newMethodInvoker(UIAction));//在主线程上执行UIAction方法
}
privatevoidUIAction()
{
this.Text="Invoked";//不会报错
}

因为Invoke的参数包括Delegate委托,因此你需要根据要Invoke的方法的参数、返回值,定义对应的Delegate,然后才能调用。在上面的例子中,UIAction方法无参数、无返回,所以直接使用了MethodInvoker这个自带的Delegate。

F. ui如何与前端对接

ui与前端对接:做ul的其实就做移动端设计的,设计一些移动端页面,当然也包括ico图标,手机上用的各种小图标,logo等,比如一个小删除按钮。

前端使用html、css、js等技术开始实现效果图的页面,同时需要和后台人员交流为后台数据留下借口和数据填充的区域等,或者获取后台数据等,这需要和后台人员合作好。

用蓝湖一键标注,下载不同格式的切图。还有设计图逻辑连线、交互说明、分状态展示、高保真原型制作预览等功能。对设计图进行树状连线,清晰展示跳转逻辑。还可在一旁添加细节说明,方便团队成员的理解。

头部内容:

这2个标记符分别表示头部信息的开始和结尾。头部中包含的标记是页面的标题、序言、说明等内容,它本身不作为内容来显示,但影响网页显示的效果。

头部中最常用的标记符是标题标记符和meta标记符,其中标题标记符用于定义网页的标题,它的内容显示在网页窗口的标题栏中,网页标题可被浏览器用做书签和收藏清单。

G. C#多线程与UI响应 跨线程更新UI

lblStatus.Text = "执行中,请稍候……"; Func<int> longTask = new Func<int>(delegate(){ // 模拟长时间任务 Thread.Sleep(2000); // 返回任务结果:5 return 5;});// 发起一次异步调用,实际上就是在.net线程池中执行longTask// 这时由于是其它线程在工作,UI线程未被阻塞,所以窗体不会假死longTask.BeginInvoke(ar =>{ // 使用EndInvoke获取到任务结果(5) int result = longTask.EndInvoke(ar); // 使用Control.Invoke方法将5显示到一个label上,如果没有Invoke, // 直接写lblStatus.Text="5",将会抛出跨线程访问UI控件的异常 Invoke(new Action(() => lblStatus.Text = "执行结果是:" + result));}, null);

H. WPF多线程操作UI的问题。

Thread t = new Thread(new ThreadStart(() => {
while(true)
Dispatcher.BeginInvoke(new Action(() => {
Window w = new Window();
w.Show();
}));
}));
t.Start();
LZ试试看呢,是不是show出了很多window
主要就是Dispatcher.BeginInvoke()这个方法

I. C# 多线程与UI响应

楼主哥哥可以使用委托,使用Delegate
我给楼主一点提示:
首先,在你要工作的类work中定义一个委托:
public delegate void refresh(string xxx);
然后,定义你的工作函数,比如你的通信函数
public void connect(string xxx){ .....;.....;label.text="ok";}//这里的label我的意思就是你所要更新的UI控件,只是一个例子,你可以在你的工作类里定义很多你需要更新的控件。
最后,在你需要调用函数function的地方,添加
function{label.BeginInvoke(new refresh(connect),"xxx");}

这样,完成你的工作类的定义

在main函数里,把你的线程绑定到这个工作函数:
Thread thread =new Thread(new ThreadStart(work.function);//这里我是新建了个线程,你可以用你自己的线程
然后,main中如果有一个label1
work.label=this.label1;//把这个label1赋到你的工作类 work中定义的那个的label,然后你就可以看到,界面中的label1的text刷新了。

跨线程调用无压力,随意调用,楼主不清楚的话,可以Message我。