當前位置:首頁 » 網頁前端 » 多線程與前端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我。