欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Service進(jìn)階詳解

Android開發(fā)例程 ? 來源:Android開發(fā)例程 ? 作者:Android開發(fā)例程 ? 2023-04-06 09:29 ? 次閱讀

上節(jié)我們學(xué)習(xí)了Service的生命周期,以及兩種啟動(dòng)Service的兩種方法,本節(jié)繼續(xù)來深入了解Service中的IntentService,Service的使用實(shí)例:前臺(tái)服務(wù)與輪詢的實(shí)現(xiàn)!

1.IntentService的使用

在上一節(jié)后我們已經(jīng)知道了如何去定義和啟動(dòng)Service,但是如果我們直接把耗時(shí)線程放到Service中的onStart()方法中,雖然可以這樣做,但是很容易會(huì)引起ANR異常(Application Not Responding),而Android的官方在介紹Service有下面這樣一段話:

直接翻譯:

1.Service不是一個(gè)單獨(dú)的進(jìn)程,它和它的應(yīng)用程序在同一個(gè)進(jìn)程中

2.Service不是一個(gè)線程,這樣就意味著我們應(yīng)該避免在Service中進(jìn)行耗時(shí)操作

于是乎,Android給我們提供了解決上述問題的替代品,就是下面要講的IntentService;IntentService是繼承與Service并處理異步請(qǐng)求的一個(gè)類,在IntentService中有一個(gè)工作線程來處理耗時(shí)操作,請(qǐng)求的Intent記錄會(huì)加入隊(duì)列。

工作流程:

客戶端通過startService(Intent)來啟動(dòng)IntentService;我們并不需要手動(dòng)地區(qū)控制IntentService,當(dāng)任務(wù)執(zhí)行完后,IntentService會(huì)自動(dòng)停止;可以啟動(dòng)IntentService多次,每個(gè)耗時(shí)操作會(huì)以工作隊(duì)列的方式在IntentService的onHandleIntent回調(diào)方法中執(zhí)行,并且每次只會(huì)執(zhí)行一個(gè)工作線程,執(zhí)行完一,再到二這樣!

再接著是代碼演示,網(wǎng)上大部分的代碼都是比較Service與IntentService的,定義足夠長(zhǎng)的休眠時(shí)間,演示Service的ANR異常,然后引出IntentService有多好!這里就不演示Service了,網(wǎng)上的都是自定義Service,然后在onStart()方法中Thread.sleep(20000)然后引發(fā)ANR異常,有興趣的可以自己寫代碼試試,這里的話只演示下IntentService的用法!

TestService3.java

public class TestService3 extends IntentService {  
    private final String TAG = "hehe";  
    //必須實(shí)現(xiàn)父類的構(gòu)造方法  
    public TestService3()  
    {  
        super("TestService3");  
    }  
  
    //必須重寫的核心方法  
    @Override  
    protected void onHandleIntent(Intent intent) {  
        //Intent是從Activity發(fā)過來的,攜帶識(shí)別參數(shù),根據(jù)參數(shù)不同執(zhí)行不同的任務(wù)  
        String action = intent.getExtras().getString("param");  
        if(action.equals("s1"))Log.i(TAG,"啟動(dòng)service1");  
        else if(action.equals("s2"))Log.i(TAG,"啟動(dòng)service2");  
        else if(action.equals("s3"))Log.i(TAG,"啟動(dòng)service3");  
          
        //讓服務(wù)休眠2秒  
        try{  
            Thread.sleep(2000);  
        }catch(InterruptedException e){e.printStackTrace();}          
    }  
  
    //重寫其他方法,用于查看方法的調(diào)用順序  
    @Override  
    public IBinder onBind(Intent intent) {  
        Log.i(TAG,"onBind");  
        return super.onBind(intent);  
    }  
  
    @Override  
    public void onCreate() {  
        Log.i(TAG,"onCreate");  
        super.onCreate();  
    }  
  
    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.i(TAG,"onStartCommand");  
        return super.onStartCommand(intent, flags, startId);  
    }  
  
  
    @Override  
    public void setIntentRedelivery(boolean enabled) {  
        super.setIntentRedelivery(enabled);  
        Log.i(TAG,"setIntentRedelivery");  
    }  
      
    @Override  
    public void onDestroy() {  
        Log.i(TAG,"onDestroy");  
        super.onDestroy();  
    }  
      
} 

AndroidManifest.xml注冊(cè)下Service

在MainActivity啟動(dòng)三次服務(wù):

public class MainActivity extends Activity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
          
        Intent it1 = new Intent("com.test.intentservice");  
        Bundle b1 = new Bundle();  
        b1.putString("param", "s1");  
        it1.putExtras(b1);  
          
        Intent it2 = new Intent("com.test.intentservice");  
        Bundle b2 = new Bundle();  
        b2.putString("param", "s2");  
        it2.putExtras(b2);  
          
        Intent it3 = new Intent("com.test.intentservice");  
        Bundle b3 = new Bundle();  
        b3.putString("param", "s3");  
        it3.putExtras(b3);  
          
        //接著啟動(dòng)多次IntentService,每次啟動(dòng),都會(huì)新建一個(gè)工作線程  
        //但始終只有一個(gè)IntentService實(shí)例  
        startService(it1);  
        startService(it2);  
        startService(it3);  
    }  
} 

運(yùn)行截圖:

poYBAGQtQ9qAQpCnAANb0xiZEy8561.png

小結(jié):

當(dāng)一個(gè)后臺(tái)的任務(wù),需要分成幾個(gè)子任務(wù),然后按先后順序執(zhí)行,子任務(wù) (簡(jiǎn)單的說就是異步操作),此時(shí)如果我們還是定義一個(gè)普通Service然后 在onStart方法中開辟線程,然后又要去控制線程,這樣顯得非常的繁瑣; 此時(shí)應(yīng)該自定義一個(gè)IntentService然后再onHandleIntent()方法中完成相關(guān)任務(wù)!

2.Activity與Service通信

我們前面的操作都是通過Activity啟動(dòng)和停止Service,假如我們啟動(dòng)的是一個(gè)下載的后臺(tái)Service,而我們想知道Service中下載任務(wù)的進(jìn)度!那么這肯定是需要Service與Activity進(jìn)行通信的,而他們之間交流的媒介就是Service中的onBind()方法!返回一個(gè)我們自定義的Binder對(duì)象!

基本流程如下:

1.自定義Service中,自定義一個(gè)Binder類,然后將需要暴露的方法都寫到該類中!

2.Service類中,實(shí)例化這個(gè)自定義Binder類,然后重寫onBind()方法,將這個(gè)Binder對(duì)象返回!

3.Activity類中實(shí)例化一個(gè)ServiceConnection對(duì)象,重寫onServiceConnected()方法,然后獲取Binder對(duì)象,然后調(diào)用相關(guān)方法即可!

3.一個(gè)簡(jiǎn)單前臺(tái)服務(wù)的實(shí)現(xiàn)

學(xué)到現(xiàn)在,我們都知道Service一般都是運(yùn)行在后來的,但是Service的系統(tǒng)優(yōu)先級(jí)還是比較低的,當(dāng)系統(tǒng)內(nèi)存不足的時(shí)候,就有可能回收正在后臺(tái)運(yùn)行的Service,對(duì)于這種情況我們可以使用前臺(tái)服務(wù),從而讓Service稍微沒那么容易被系統(tǒng)殺死,當(dāng)然還是有可能被殺死的...所謂的前臺(tái)服務(wù)就是狀態(tài)欄顯示的Notification!

實(shí)現(xiàn)起來也很簡(jiǎn)單,最近做的項(xiàng)目剛好用到這個(gè)前臺(tái)服務(wù),就把核心的代碼摳出來分享下:

在自定義的Service類中,重寫onCreate(),然后根據(jù)自己的需求定制Notification;定制完畢后,調(diào)用startForeground(1,notification對(duì)象)即可!

核心代碼如下:

public void onCreate()
{
    super.onCreate();
    Notification.Builder localBuilder = new Notification.Builder(this);
    localBuilder.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0));
    localBuilder.setAutoCancel(false);
    localBuilder.setSmallIcon(R.mipmap.ic_cow_icon);
    localBuilder.setTicker("Foreground Service Start");
    localBuilder.setContentTitle("Socket服務(wù)端");
    localBuilder.setContentText("正在運(yùn)行...");
    startForeground(1, localBuilder.getNotification());
}

運(yùn)行效果截圖:

4.簡(jiǎn)單定時(shí)后臺(tái)線程的實(shí)現(xiàn)

除了上述的前臺(tái)服務(wù)外,實(shí)際開發(fā)中Service還有一種常見的用法,就是執(zhí)行定時(shí)任務(wù),比如輪詢,就是每間隔一段時(shí)間就請(qǐng)求一次服務(wù)器,確認(rèn)客戶端狀態(tài)或者進(jìn)行信息更新等!而Android中給我們提供的定時(shí)方式有兩種使用Timer類與Alarm機(jī)制!

前者不適合于需要長(zhǎng)期在后臺(tái)運(yùn)行的定時(shí)任務(wù),CPU一旦休眠,Timer中的定時(shí)任務(wù)就無法運(yùn)行;Alarm則不存在這種情況,他具有喚醒CPU的功能,另外,也要區(qū)分CPU喚醒與屏幕喚醒!

使用流程:

Step 1:獲得Service:AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);

Step 2:通過set方法設(shè)置定時(shí)任務(wù)int anHour = 2 * 1000;long triggerAtTime = SystemClock.elapsedRealtime() + anHour;manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,pendingIntent);

Step 3:定義一個(gè)Service在onStartCommand中開辟一條事務(wù)線程,用于處理一些定時(shí)邏輯

Step 4:定義一個(gè)Broadcast(廣播),用于啟動(dòng)Service最后別忘了,在AndroidManifest.xml中對(duì)這Service與Boradcast進(jìn)行注冊(cè)!

參數(shù)詳解:set(int type,long startTime,PendingIntent pi)

①type:有五個(gè)可選值:

AlarmManager.ELAPSED_REALTIME:鬧鐘在手機(jī)睡眠狀態(tài)下不可用,該狀態(tài)下鬧鐘使用相對(duì)時(shí)間(相對(duì)于系統(tǒng)啟動(dòng)開始),狀態(tài)值為3;

AlarmManager.ELAPSED_REALTIME_WAKEUP鬧鐘在睡眠狀態(tài)下會(huì)喚醒系統(tǒng)并執(zhí)行提示功能,該狀態(tài)下鬧鐘也使用相對(duì)時(shí)間,狀態(tài)值為2;

AlarmManager.RTC鬧鐘在睡眠狀態(tài)下不可用,該狀態(tài)下鬧鐘使用絕對(duì)時(shí)間,即當(dāng)前系統(tǒng)時(shí)間,狀態(tài)值為1;

AlarmManager.RTC_WAKEUP表示鬧鐘在睡眠狀態(tài)下會(huì)喚醒系統(tǒng)并執(zhí)行提示功能,該狀態(tài)下鬧鐘使用絕對(duì)時(shí)間,狀態(tài)值為0;

AlarmManager.POWER_OFF_WAKEUP表示鬧鐘在手機(jī)關(guān)機(jī)狀態(tài)下也能正常進(jìn)行提示功能,所以是5個(gè)狀態(tài)中用的最多的狀態(tài)之一,該狀態(tài)下鬧鐘也是用絕對(duì)時(shí)間,狀態(tài)值為4;不過本狀態(tài)好像受SDK版本影響,某些版本并不支持;

PS:第一個(gè)參數(shù)決定第二個(gè)參數(shù)的類型,如果是REALTIME的話就用:SystemClock.elapsedRealtime( )方法可以獲得系統(tǒng)開機(jī)到現(xiàn)在經(jīng)歷的毫秒數(shù)如果是RTC的就用:System.currentTimeMillis()可獲得從1970.1.1 0點(diǎn)到現(xiàn)在做經(jīng)歷的毫秒數(shù)。

②startTime: 鬧鐘的第一次執(zhí)行時(shí)間,以毫秒為單位,可以自定義時(shí)間,不過一般使用當(dāng)前時(shí)間。 需要注意的是,本屬性與第一個(gè)屬性(type)密切相關(guān),如果第一個(gè)參數(shù)對(duì)應(yīng)的鬧鐘 使用的是相對(duì)時(shí)間(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本屬 性就得使用相對(duì)時(shí)間(相對(duì)于系統(tǒng)啟動(dòng)時(shí)間來說),比如當(dāng)前時(shí)間就表示為: SystemClock.elapsedRealtime();如果第一個(gè)參數(shù)對(duì)應(yīng)的鬧鐘使用的是絕對(duì)時(shí)間 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本屬性就得使用絕對(duì)時(shí)間, 比如當(dāng)前時(shí)間就表示為:System.currentTimeMillis()。

③PendingIntent: 綁定了鬧鐘的執(zhí)行動(dòng)作,比如發(fā)送一個(gè)廣播、給出提示等等。PendingIntent 是Intent的封裝類。
需要注意的是,如果是通過啟動(dòng)服務(wù)來實(shí)現(xiàn)鬧鐘提示的話, PendingIntent對(duì)象的獲取就應(yīng)該采用Pending.getService (Context c,int i,Intent intent,int j)方法;
如果是通過廣播來實(shí)現(xiàn)鬧鐘提示的話, PendingIntent對(duì)象的獲取就應(yīng)該采用 PendingIntent.getBroadcast (Context c,int i,Intent intent,int j)方法;
如果是采用Activity的方式來實(shí)現(xiàn)鬧鐘提示的話,PendingIntent對(duì)象的獲取 就應(yīng)該采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j) 方法。
如果這三種方法錯(cuò)用了的話,雖然不會(huì)報(bào)錯(cuò),但是看不到鬧鐘提示效果。

另外:

從4.4版本后(API 19),Alarm任務(wù)的觸發(fā)時(shí)間可能變得不準(zhǔn)確,有可能會(huì)延時(shí),是系統(tǒng)對(duì)于耗電性的優(yōu)化,如果需要準(zhǔn)確無誤可以調(diào)用setExtra()方法~

核心代碼:

public class LongRunningService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //這里開辟一條線程,用來執(zhí)行具體的邏輯操作:
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("BackService", new Date().toString());
            }
        }).start();
        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        //這里是定時(shí)的,這里設(shè)置的是每隔兩秒打印一次時(shí)間=-=,自己改
        int anHour = 2 * 1000;
        long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
        Intent i = new Intent(this,AlarmReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        return super.onStartCommand(intent, flags, startId);
    }
}

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context,LongRunningService.class);
        context.startService(i);
    }
}
審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3798

    瀏覽量

    81464
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4837

    瀏覽量

    69131
  • Service
    +關(guān)注

    關(guān)注

    0

    文章

    30

    瀏覽量

    13836
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    507

    瀏覽量

    19764
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【shell腳本進(jìn)階】幾個(gè)常用的shell進(jìn)階腳本

    【shell腳本進(jìn)階】幾個(gè)常用的shell進(jìn)階腳本
    的頭像 發(fā)表于 09-19 08:59 ?1972次閱讀
    【shell腳本<b class='flag-5'>進(jìn)階</b>】幾個(gè)常用的shell<b class='flag-5'>進(jìn)階</b>腳本

    Service Guide Agilent Technolo

    Service Gu
    發(fā)表于 08-18 16:58 ?24次下載

    什么是ASP/Application Service Pro

    什么是ASP,Application Service Provider  英文縮寫: ASP,Application Service Provider 中文譯名: 應(yīng)用服務(wù)提供者
    發(fā)表于 02-22 09:54 ?861次閱讀

    什么是ASP (Application Service Pr

    什么是ASP (Application Service Provider)  英文縮寫: ASP (Application Service Provider) 中文譯名: 應(yīng)用服務(wù)提供商
    發(fā)表于 02-22 09:55 ?1191次閱讀

    什么是Application Courier Service

    什么是Application Courier Service  英文縮寫: Application Courier Service 中文譯名: 應(yīng)用向?qū)Х?wù) 分  類: IP與多媒體
    發(fā)表于 02-22 10:08 ?809次閱讀

    什么是CoS (Class of Service)

    什么是CoS (Class of Service)  英文縮寫: CoS (Class of Service) 中文譯名: 服務(wù)類別 分  類: 解  釋: 為了解決IP
    發(fā)表于 02-22 17:20 ?2170次閱讀

    什么是Universal Service

    什么是Universal Service  英文縮寫: Universal Service 中文譯名: 普遍服務(wù) 分  類: IP與多媒體 解  釋: 指電信
    發(fā)表于 02-23 09:43 ?781次閱讀

    Web Service的架構(gòu)與協(xié)議

    文章介紹了Web Service 產(chǎn)生的起因,對(duì)Web Service 的體系結(jié)構(gòu),以及構(gòu)成它的各協(xié)議進(jìn)行了分析,并對(duì)其應(yīng)用前景進(jìn)行了探討。
    發(fā)表于 06-30 10:43 ?42次下載
    Web <b class='flag-5'>Service</b>的架構(gòu)與協(xié)議

    NB3000_Audio_Service

    NB3000 Audio Service,好東西,喜歡的朋友可以下載來學(xué)習(xí)。
    發(fā)表于 02-18 16:43 ?0次下載

    Audio_Service

    Audio Service,好東西,喜歡的朋友可以下載來學(xué)習(xí)。
    發(fā)表于 02-22 14:21 ?0次下載

    Instrument_Service

    Instrument Service,好東西,喜歡的朋友可以下載來學(xué)習(xí)。
    發(fā)表于 02-22 14:53 ?0次下載

    Yamaha_CDX-E100_Service_Manual

    Yamaha CDX-E100 Service Manual
    發(fā)表于 02-22 15:10 ?3次下載

    黑客攻防入門與進(jìn)階ddd

    黑客攻防入門與進(jìn)階ddd黑客攻防入門與進(jìn)階ddd
    發(fā)表于 02-23 15:45 ?9次下載

    Vivado使用誤區(qū)與進(jìn)階

    《Vivado使用誤區(qū)與進(jìn)階》電子書匯集了賽靈思專家團(tuán)隊(duì)在客戶支持時(shí)所碰見的諸多實(shí)際案例,以及相對(duì)應(yīng)的解決方案;還有多年總結(jié)下來的設(shè)計(jì)技巧與代碼參數(shù)詳解。是您學(xué)習(xí)和掌握Vivado開發(fā)套件的一本不可多得的實(shí)戰(zhàn)指導(dǎo)資料。
    發(fā)表于 08-03 19:37 ?84次下載

    C語言的進(jìn)階學(xué)習(xí)課件資料合集

    本文檔的主要內(nèi)容詳細(xì)介紹的是C語言的進(jìn)階學(xué)習(xí)課件資料合集包括了:第1節(jié)-數(shù)據(jù)的存儲(chǔ),第2節(jié)-指針的進(jìn)階,第3節(jié)-字符串+內(nèi)存函數(shù)的介紹,第4節(jié)-自定義類型詳解(結(jié)構(gòu)體+枚舉+聯(lián)合),第5節(jié)-動(dòng)態(tài)內(nèi)存管理,第6節(jié)-文件操作,第7節(jié)
    發(fā)表于 07-14 08:00 ?11次下載
    C語言的<b class='flag-5'>進(jìn)階</b>學(xué)習(xí)課件資料合集