Android 服務(Service)

一、服務的解釋

服務(Service)是Android中實現后臺運行的解決方案,它適合那些去執行不需要和用戶交互而且還要求長期運行的任務。服務的運行不依賴任何的與任何用戶界面,即使程序被切換到后臺,或者用戶打開了另外一個應用程序,服務仍然能夠保持正常運行。

注意:服務并不是運行在一個獨立的進程當中,而是依賴于創建服務時所在的應用程序進程。當某個應用程序被殺死時,所有依賴于該進程的服務也會停止運行。

服務并不會自動開啟線程,所有的代碼都是默認運行在主線程中的。我們在服務的內部手動創建了子線程,并在這里執行具體的任務,否則就有可能出現主線程被阻塞住的情況。

二、Android多線程編程

1、線程的基本用法

這部分與Java相同,線程創建的兩種方式。

2、在子線程中更新UI

與其他許多的GUI庫一樣,Android的UI也是不安全的。也就是說,如果想要更新應用程序的UI元素,則必須在主線程中進行,否則就會出現異常。

實踐:新建AndroidThreadTest項目:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.zhj.androidthreadtest.MainActivity"><Buttonandroid:id="@+id/change_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Change Text"/><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="Hello world"android:textSize="20sp"/>
</RelativeLayout>

一個按鈕,一個TextView,顯示出Hello world,目標效果:當我們點擊按鈕時,會把Hello world 改變成 Nice to meet you。

我們開始寫MainActivity.java

package com.zhj.androidthreadtest;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private TextView text;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text =(TextView)findViewById(R.id.text);Button changeText = (Button)findViewById(R.id.change_text);changeText.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {switch(v.getId()){case R.id.change_text:new Thread(new Runnable() {@Overridepublic void run() {text.setText("Nice to meet you");}}).start();break;default:break;}}});}
}

邏輯非常簡單。我們在 按鈕的點擊事件中開啟了一個子線程,然后在子線程中調用TextView的setText()方法將顯示的字符串改成Nice to meet you。我們運行之后,點擊按鈕按鈕發現程序崩潰了。

查看logcat日志:可以看出由于在子線程中更新UI造成的。


由此證實,An'd'roid確實不允許在子線程中進行UI操作的。但是有些時候我們必須在子線程中去執行一些耗時任務,然后根據任務的執行結果來更新相應的UI控件。

對于這種情況,Android 提供了一套異步消息處理機制,完美解決了在子線程中進行UI操作的問題。我們先來了解一下異步消息處理的使用方法,

修改MainActivity的代碼:

package com.zhj.androidthreadtest;import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {public static final int UPDATE_TEXT = 1; //表示更新TextView這個動作private TextView text;private Handler handler = new Handler(){//新增Handler對象,并重寫handleMessage()方法,對具體的Message進行處理,public void handleMessage(Message msg){//如果發現Message的what字段的值等于UPDATA_TEXT,就將TextView顯示的內容改成Nice to meet youswitch (msg.what){case UPDATE_TEXT ://在這里進行UI操作text.setText("Nice to meet you");break;default:break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text =(TextView)findViewById(R.id.text);Button changeText = (Button)findViewById(R.id.change_text);changeText.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {switch(v.getId()){case R.id.change_text:new Thread(new Runnable() {@Overridepublic void run() {Message message = new Message();//創建一個Message(android.os.Message)對象,并將他的what字段設置為UPDATE_TEXTmessage.what = UPDATE_TEXT;handler.sendMessage(message);//將Message對象發送出去}}).start();break;default:break;}}});}
}

來觀察按鈕的點擊事件中的代碼,我們并沒有在子線程里直接進行UI操作,而是創建了一個Message(android.os.Message)對象,并將它的what字段指定為UPDATE_TEXT,然后調用Handler的sendMessage()方法將這條Message發送出去。Handler會收到這條Message,并在handlerMessage()方法中對它進行處理,注意此時的handlerMessage()方法中的代碼就是在主線程中運行的了,所以我們放心在這里進行UI操作。

運行之后,我們會發現內容被替換成Nice to meet you 。

3、解析異步消息處理機制

Android中的異步消息處理主要分為4個部分:Message、Handler、MessageQueue和Looper。

? ? (1)Message:Message是在線程之間傳遞的消息,它可以在內部攜帶少量的信息,用于在不同線程之間交換數據,可以使用Message的what字段,還可以使用arg1和arg2字段來攜帶一些整型數據,使用obj字段攜帶一個Object對象。

? ? (2)Handler:處理者的意思,主要用于發送和處理消息的,發送消息一般是使用Handler的sendMessage()方法,而發出的消息經過一系列的輾轉處理后,最終會傳遞到Handler的handleMessage()方法中。

????(3)MessageQueue:消息隊列,主要用于存放所有通過Handler發送的消息。這部分消息會一直存放在消息隊列中,等待被處理。每個線程中只有一個MessageQueue對象。

? ? (4)Looper:每個線程中的MessageQueue的管家,調用Looper的loop()方法后,就會進入到一個無限循環當中,然后每當發現MessageQueue中存在一條消息,就會將它取出,并傳遞到Handler的handlerMessage()方法中。每個線程中也只有要給Looper對象。

我們把異步消息處理的整個流程再梳理一遍。首先需要在主線程中創建一個Handler對象,并重寫handlerMessage()方法,這個方法里寫你的邏輯。當主線程中需要進行UI操作時,就創建一個Message對象,并通過Handler把這條消息發送出去。之后這條消息會被添加到MessageQueue的隊列中等待被處理,而Looper則會一直嘗試從MessageQueue中取出待處理消息,最后分發回Handler的handlerMessage()方法中。由于Handler是在主線程中創建的,所以此時handlerMessage()方法中的代碼也會在主線程中運行,于是我們在這里可以進行UI操作了。


一條Message經過這樣一個流程的輾轉調用后,也就從子線程進入到了主線程,從不能更新UI變成了更新UI,整個異步消息處理的核心思想就是如下。

4、使用AsyncTask


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273998.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273998.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273998.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CenOS 配置C/C++語言

1.下載eclipseCDT組合包。 2.電腦上安裝GCC&#xff0c; G 3.在eclipse上創建一個C project 4. Eclipse CDT功能很強大&#xff0c;安裝完雖然可以編譯運行c程序&#xff0c;但有個問題&#xff0c;就是找不到c標準庫的頭文件&#xff0c;無法打開諸如之類的文件&#xff0c;編…

(數據結構)前綴,后綴以及中綴表達式

中綴表達式&#xff08;中綴記法&#xff09; 中綴表達式是一種通用的算術或邏輯公式表示方法&#xff0c;操作符以中綴形式處于操作數的中間。中綴表達式是人們常用的算術表示方法。 前綴表達式&#xff08;前綴記法、波蘭式&#xff09; 前綴表達式是一種沒有括號的算術表…

Moravec角點檢測算子

Moravec角點檢測算子 Moravec 在1981年提出Moravec角點檢測算子[1]&#xff0c;并將它應用于立體匹配。 首先, 計算每個像素點的興趣值, 即以該像素點為中心, 取一個w*w(如:5x5)的方形窗口, 計算0度、45度、90度、135度四個方向灰度差的平方和, 取其中的最小值作為該像素點的興…

java習題-練習1

1、 Given the string, check if it is a palindrome.&#xff08;回文&#xff09; Example For inputString "aabaa", the output should becheckPalindrome(inputString) true;For inputString "abac", the output should becheckPalindrome(inputSt…

文件夾生成工具

很簡單的一個小工具,輸入一個字符串,可以為你生成相應的文件夾. 至于有什么用?我公司一個策劃拿一頓飯給我要的. 下載地址: http://pan.baidu.com/s/1d0ewl 轉載于:https://www.cnblogs.com/WhyEngine/p/3350053.html

java中System.exit(1)、System.exit(0)、以及return的區別

System.exit(0)是正常退出程序&#xff0c;而System.exit(1)或者說非0表示非正常退出程序System.exit(status)不管status為何值都會退出程序。 和return 相比有以下不同點&#xff1a;return是回到上一層&#xff0c;而System.exit(status)是回到最上層

(轉載)深入理解Linux中內存管理---分段與分頁簡介

首先&#xff0c;必須要闡述一下這篇文章的主題是Linux內存管理中的分段和分頁技術。 來回顧一下歷史&#xff0c;在早期的計算機中&#xff0c;程序是直接運行在物理內存上的。換句話說&#xff0c;就是程序在運行的過程中訪問的都是物理地址。如果這個系統只運行一個程序&…

eclipse解決Android Library Project jar包重復導致的問題

Android Studio部分情況下用起來還是有些不適應的地方&#xff0c;用eclipse熟練了&#xff0c;在趕項目進度的情況下還得重拾eclipse。下面是今天碰到的一個老問題。 1.在導入Android Library工程文件的時候要把library一起拷貝到workspace中 2.在導入的Android Library工程文…

java中main函數的args參數

先說一下args的作用&#xff1a;我們習慣將一些有用的參數傳遞給我們定義的函數&#xff0c;那么可曾想過有參數傳遞給main函數&#xff1f;args就是傳遞給main函數的一個數組參數。可是main函數作為程序(application程序)的入口點&#xff0c;是由系統自動調用的&#xff0c;怎…

算法:排序算法的比較

默認為遞增順序&#xff1b;注&#xff1a;一下例子希望自己再次復習時&#xff0c;可以用筆在紙上畫畫內存圖。 包括有: 選擇排序冒泡排序插入排序 1.選擇排序 <--------------------------------------選擇排序---------------------------------------> 1、選擇排…

LTTng 簡介使用實戰

一、LTTng簡介 LTTng: (Linux Trace Toolkit Next Generation),它是用于跟蹤 Linux 內核、應用程序以及庫的系統軟件包。LTTng 主要由內核模塊和動態鏈接庫(用于應用程序和動態鏈接庫的跟蹤)組成。它由一個會話守護進程控制,該守護進程接受來自命令行接口的命令。babeltrace 項…

黑馬程序員-------------(十)Java基礎知識加強(一)

JDK1.5新特性 目錄1.之前已經學習過的JDK1.5新特性2.靜態導入 StaticImport3.可變參數 ...4.高級for循環5.枚舉6.泛型 Generic7.注解注&#xff1a;本章全部為重點內容。###################################################################################################…

java例子:數組 數3退1

500個人圍成一個圈子&#xff0c;數夠3人&#xff0c;就退出1個&#xff0c;問最后剩下的是幾號&#xff1f;檢驗先有5個人&#xff0c;應該留下第4個人&#xff0c;由于是數組&#xff0c;所以第四個人的下標是3. /*achieve the funtion :count 3 kids, the quit the third k…

Android版CCLabelTTF在setstring時出現黑塊

首先有個前提知識&#xff0c;cocos2dx里&#xff0c;只能在ui線程&#xff08;通常也就是主線程&#xff09;中進行渲染工作&#xff08;貌似現在有一些引擎是支持多線程渲染的&#xff0c;沒有深入研究&#xff09;&#xff0c;否則大約會因為多個線程同時給GPU發指令而出現問…

java例子:九九乘法表

來吧直接上代碼&#xff1a;public class Test{public static void main(String[] args) {for(int i 1; i<9;i){for (int j 1; j < i ;j ) {System.out.print(j"x"i""j*i" ");}System.out.print("\n");}} }運行之后&#xff1…

Apache的RewriteRule規則詳細介紹

R[code](force redirect) 強制外部重定向 (rkyW z強制在替代字符串加上http://thishost[:thisport]/前綴重定向到外部的URL.如果code不指定&#xff0c;將用缺省的302 HTTP狀態碼。 gN24M 3{CF(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。 m> 4ahue$G(force URL…

算法:查找

查找算法&#xff08;比較&#xff09;基本思想順序查找順序查找也稱為線形查找&#xff0c;屬于無序查找算法。從數據結構線形表的一端開始&#xff0c;順序掃描&#xff0c;依次將掃描到的結點關鍵字與給定值k相比較&#xff0c;若相等則表示查找成功&#xff1b;若掃描結束仍…

query上傳插件uploadify參數詳細分析

query上傳插件uploadify參數詳細分析 Uploadify Version 3.2 官網&#xff1a;http://www.uploadify.com/ 注&#xff1a;文件包里有兩個js分別是&#xff1a;jquery.uploadify.js 和 jquery.uploadify.min.js&#xff0c;兩者其實一樣&#xff0c;只需載入其中一個js即可。很明…

python 基礎 list和 tuple dict和set

list Python內置的一種數據類型是列表&#xff1a;list。list是一種有序的集合&#xff0c;可以隨時添加和刪除其中的元素。classmates [Michael, Bob, Tracy] 要刪除list末尾的元素&#xff0c;用pop()方法&#xff1a; 要刪除指定位置的元素&#xff0c;用pop(i)方法&#x…

IIS的安裝

xp上好像只能裝IIS5&#xff0c;IIS6根本就裝不了轉載于:https://www.cnblogs.com/hyk110988/p/3372592.html