㈠ android客戶端怎麼與伺服器資料庫連接
不能與資料庫連接的
Android客戶端不能直接與伺服器資料庫連接。資料庫是需要非常大的內存,安裝之後有好幾G,連接資料庫要有一個像SQLServer里的webservice,這樣的一個橋梁來間接訪問。就是在伺服器運行一個服務端程序,該服務端程序通過接收來自android客戶端的指令,對資料庫進行操作。
客戶端的http請求可以通過 HttpClient類實現,在anddroid 4.0之後,客戶端的網路請求已經不被允許在主線程中運行,所以還需注意另開啟一個子線程進行網路請求。
(1)子線程資料庫android擴展閱讀:
Android安全許可權機制:
Android默認設置下,所有應用都沒有許可權對其他應用、系統或用戶進行較大影響的操作。這其中包括讀寫用戶隱私數據(聯系人或電子郵件),讀寫其他應用文件,訪問網路或阻止設備待機等。安裝應用時,在檢查程序簽名提及的許可權,且經過用戶確認後,軟體包安裝器會給予應用許可權。
下載一款Android應用通常會要求如下的許可權:撥打電話、發送簡訊或彩信、修改/刪除SD卡上的內容、讀取聯系人的信息、讀取日程信的息,寫入日程數據、讀取電話狀態或識別碼、精確的(基於GPS)地理位置、模糊的(基於網路獲取)地理位置、創建藍牙連接、
還有對互聯網的完全訪問、查看網路狀態,查看WiFi狀態、避免手機待機、修改系統全局設置、讀取同步設定、開機自啟動、重啟其他應用、終止運行中的應用、設定偏好應用、震動控制、拍攝圖片等。
㈡ android 資料庫操作可以放在子線程裡面嗎
mysql是免費資料庫,市場普及率非常高,而新建資料庫就得一切從0來,收費還是不收費?編個新資料庫技術並不難,難在資料庫標准化機構是美國的,美國大嘴一張,整個資料庫就得重改這裡面的維護預算誰給出?
㈢ Android 如何創建子線程以及區分主線程
在一個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。
㈣ android 非同步方法和子線程方法有什麼區別
子線程沒有控制並發數量,當並發過多的時候非同步方法的作用就體現出來了。
非同步是相對於同步而言的,顧名思義,同步就是各個通訊節點之間有統一的時鍾,按照相同的時鍾工作,非同步相反,各節點之間沒有統一的時鍾,每個節點按照自己內部的時鍾工作。
android在所有Thread當中,有一個Thread,我們稱之為UI Thread。UI
Thread在Android程序運行的時候就被創建,是一個Process當中的主線程Main
Thread,主要是負責控制UI界面的顯示、更新和控制項交互。在Android程序創建之初,一個Process呈現的是單線程模型,所有的任務都在一個線程中運行。因此,我們認為,UI
Thread所執行的每一個函數,所花費的時間都應該是越短越好。而其他比較費時的工作(訪問網路,下載數據,查詢資料庫等),都應該交由子線程去執行,以免阻塞主線程。
㈤ Android如何將數據從子線程中傳到主線程
這個谷歌早已經給你實現了,使用handler:
例如在主線程創建handler
子線程發消息到這個handler
Handler handler=new Handler(){
@Override
public boolean handleMessage(Message msg){
switch (msg.what){
case 1:
//TODO
break;
}
}
//子線程里
Message msg = new Message();
msg.what = 1;
msg.object=XX;//傳對象,還有arg1、arg2……
handler.sendMessage(msg);
㈥ Android 中的「子線程」解析
Android 中線程可分為 主線程 和 子線程 兩類,其中主線程也就是 UI線程 ,它的主要這作用就是運行四大組件、處理界面交互。子線程則主要是處理耗時任務,也是我們要重點分析的。
首先 Java 中的各種線程在 Android 里是通用的,Android 特有的線程形態也是基於 Java 的實現的,所以有必要先簡單的了解下 Java 中的線程,本文主要包括以下內容:
在 Java 中要創建子線程可以直接繼承 Thread 類,重寫 run() 方法:
或者實現 Runnable 介面,然後用Thread執行Runnable,這種方式比較常用:
簡單的總結下:
Callable 和 Runnable 類似,都可以用來處理具體的耗時任務邏輯的,但是但具體的差別在哪裡呢?看一個小例子:
定義 MyCallable 實現了 Callable 介面,和之前 Runnable 的 run() 方法對比下, call() 方法是有返回值的哦,泛型就是返回值的類型:
一般會通過線程池來執行 Callable (線程池相關內容後邊會講到),執行結果就是一個 Future 對象:
可以看到,通過線程池執行 MyCallable 對象返回了一個 Future 對象,取出執行結果。
Future 是一個介面,從其內部的方法可以看出它提供了取消任務(有坑!!!)、判斷任務是否完成、獲取任務結果的功能:
Future 介面有一個 FutureTask 實現類,同時 FutureTask 也實現了 Runnable 介面,並提供了兩個構造函數:
用 FutureTask 一個參數的構造函數來改造下上邊的例子:
FutureTask 內部有一個 done() 方法,代表 Callable 中的任務已經結束,可以用來獲取執行結果:
所以 Future + Callable 的組合可以更方便的獲取子線程任務的執行結果,更好的控制任務的執行,主要的用法先說這么多了,其實 AsyncTask 內部也是類似的實現!
注意, Future 並不能取消掉運行中的任務,這點在後邊的 AsyncTask 解析中有提到。
Java 中線程池的具體的實現類是 ThreadPoolExecutor ,繼承了 Executor 介面,這些線程池在 Android 中也是通用的。使用線程池的好處:
常用的構造函數如下:
一個常規線程池可以按照如下方式來實現:
執行任務:
基於 ThreadPoolExecutor ,系統擴展了幾類具有新特性的線程池:
線程池可以通過 execute() 、 submit() 方法開始執行任務,主要差別從方法的聲明就可以看出,由於 submit() 有返回值,可以方便得到任務的執行結果:
要關閉線程池可以使用如下方法:
IntentService 是 Android 中一種特殊的 Service,可用於執行後台耗時任務,任務結束時會自動停止,由於屬於系統的四大組件之一,相比一般線程具有較高的優先順序,不容易被殺死。用法和普通 Service 基本一致,只需要在 onHandleIntent() 中處理耗時任務即可:
至於 HandlerThread,它是 IntentService 內部實現的重要部分,細節內容會在 IntentService 源碼中說到。
IntentService 首次創建被啟動的時候其生命周期方法 onCreate() 會先被調用,所以我們從這個方法開始分析:
這里出現了 HandlerThread 和 ServiceHandler 兩個類,先搞明白它們的作用,以便後續的分析。
首先看 HandlerThread 的核心實現:
首先它繼承了 Thread 類,可以當做子線程來使用,並在 run() 方法中創建了一個消息循環系統、開啟消息循環。
ServiceHandler 是 IntentService 的內部類,繼承了 Handler,具體內容後續分析:
現在回過頭來看 onCreate() 方法主要是一些初始化的操作, 首先創建了一個 thread 對象,並啟動線程,然後用其內部的 Looper 對象 創建一個 mServiceHandler 對象,將子線程的 Looper 和 ServiceHandler 建立了綁定關系,這樣就可以使用 mServiceHandler 將消息發送到子線程去處理了。
生命周期方法 onStartCommand() 方法會在 IntentService 每次被啟動時調用,一般會這里處理啟動 IntentService 傳遞 Intent 解析攜帶的數據:
又調用了 start() 方法:
就是用 mServiceHandler 發送了一條包含 startId 和 intent 的消息,消息的發送還是在主線程進行的,接下來消息的接收、處理就是在子線程進行的:
當接收到消息時,通過 onHandleIntent() 方法在子線程處理 intent 對象, onHandleIntent() 方法執行結束後,通過 stopSelf(msg.arg1) 等待所有消息處理完畢後終止服務。
為什麼消息的處理是在子線程呢?這里涉及到 Handler 的內部消息機制,簡單的說,因為 ServiceHandler 使用的 Looper 對象就是在 HandlerThread 這個子線程類里創建的,並通過 Looper.loop() 開啟消息循環,不斷從消息隊列(單鏈表)中取出消息,並執行,截取 loop() 的部分源碼:
dispatchMessage() 方法間接會調用 handleMessage() 方法,所以最終 onHandleIntent() 就在子線程中劃線執行了,即 HandlerThread 的 run() 方法。
這就是 IntentService 實現的核心,通過 HandlerThread + Hanlder 把啟動 IntentService 的 Intent 從主線程切換到子線程,實現讓 Service 可以處理耗時任務的功能!
AsyncTask 是 Android 中輕量級的非同步任務抽象類,它的內部主要由線程池以及 Handler 實現,在線程池中執行耗時任務並把結果通過 Handler 機制中轉到主線程以實現UI操作。典型的用法如下:
從 Android3.0 開始,AsyncTask 默認是串列執行的:
如果需要並行執行可以這么做:
AsyncTask 的源碼不多,還是比較容易理解的。根據上邊的用法,可以從 execute() 方法開始我們的分析:
看到 @MainThread 註解了嗎?所以 execute() 方法需要在主線程執行哦!
進而又調用了 executeOnExecutor() :
可以看到,當任務正在執行或者已經完成,如果又被執行會拋出異常!回調方法 onPreExecute() 最先被執行了。
傳入的 sDefaultExecutor 參數,是一個自定義的串列線程池對象,所有任務在該線程池中排隊執行:
可以看到 SerialExecutor 線程池僅用於任務的排隊, THREAD_POOL_EXECUTOR 線程池才是用於執行真正的任務,就是我們線程池部分講到的 ThreadPoolExecutor :
再回到 executeOnExecutor() 方法中,那麼 exec.execute(mFuture) 就是觸發線程池開始執行任務的操作了。
那 executeOnExecutor() 方法中的 mWorker 是什麼? mFuture 是什麼?答案在 AsyncTask 的構造函數中:
原來 mWorker 是一個 Callable 對象, mFuture 是一個 FutureTask 對象,繼承了 Runnable 介面。所以 mWorker 的 call() 方法會在 mFuture 的 run() 方法中執行,所以 mWorker 的 call() 方法在線程池得到執行!
同時 doInBackground() 方法就在 call() 中方法,所以我們自定義的耗時任務邏輯得到執行,不就是我們第二部分講的那一套嗎!
doInBackground() 的返回值會傳遞給 postResult() 方法:
就是通過 Handler 將最終的耗時任務結果從子線程發送到主線程,具體的過程是這樣的, getHandler() 得到的就是 AsyncTask 構造函數中初始化的 mHandler , mHander 又是通過 getMainHandler() 賦值的:
可以在看到 sHandler 是一個 InternalHandler 類對象:
所以 getHandler() 就是在得到在主線程創建的 InternalHandler 對象,所以
就可以完成耗時任務結果從子線程到主線程的切換,進而可以進行相關UI操作了。
當消息是 MESSAGE_POST_RESULT 時,代表任務執行完成, finish() 方法被調用:
如果任務沒有被取消的話執行 onPostExecute() ,否則執行 onCancelled() 。
如果消息是 MESSAGE_POST_PROGRESS , onProgressUpdate() 方法被執行,根據之前的用法可以 onProgressUpdate() 的執行需要我們手動調用 publishProgress() 方法,就是通過 Handler 來發送進度數據:
進行中的任務如何取消呢?AsyncTask 提供了一個 cancel(boolean mayInterruptIfRunning) ,參數代表是否中斷正在執行的線程任務,但是呢並不靠譜, cancel() 的方法注釋中有這么一段:
大致意思就是調用 cancel() 方法後, onCancelled(Object) 回調方法會在 doInBackground() 之後被執行而 onPostExecute() 將不會被執行,同時你應該 doInBackground() 回調方法中通過 isCancelled() 來檢查任務是否已取消,進而去終止任務的執行!
所以只能自己動手了:
AsyncTask 整體的實現流程就這些了,源碼是最好的老師,自己跟著源碼走一遍有些問題可能就豁然開朗了!
㈦ android應用程序開發,為串口接收數據創建的子線程問題,急!
找Bug應該要有條理,我們首先不能確定"每次都去執行while(value2 != 1)以外的代碼",因為程序執行的很快,可能收發很快,循環每妙執行多少次不確定,而且你的阻塞時間還是0,最好循環內外加上輸出判斷是不是每次都執行循環體外的代碼。
再就是你創建的是兩個循環,開頭
fd = HardwareControler.openSerialPort("/dev/ttyUSB0", buaterate, 8, 1);
每次讀取完數據都會給fd重新賦值, 不確定打開串口是否有應答數據,如果有的話
打開串口->應答數據->有數據,執行第二個循環->讀數據->重新第一個循環
這樣可能會一直有數據,可把fd = HardwareControler.openSerialPort("/dev/ttyUSB0", buaterate, 8, 1);放到第一個循環外面。
這些只是推測,需要你根據自己代碼慢慢調試。