從瓶頸到精通——Android四大組件:Service

今天記錄一篇關於Service的文章
1.Service的一般使用
2.startService和bindService的區別
3.多進程下使用Service
4.Service中引用一個windowManager

1.Service的一般使用
Service繼承自ContextWrapper,表明它本身也是一個Context。瞭解它的繼承關係更有利於瞭解Service
Service也有自己的生命週期
onCreate:Service的初始化
onStart:啓動服務
onStartCommand:開始服務
onDestroy:銷燬服務
onLowMemory:
在系統內存不足,所有後臺程序(優先級爲background的進程,不是指後臺運行的進程)都被殺死時,系統會調用OnLowMemory。
onTrimMemory:
OnTrimMemory的參數是一個int數值,代表不同的內存狀態:
TRIM_MEMORY_COMPLETE:內存不足,並且該進程在後臺進程列表最後一個,馬上就要被清理
TRIM_MEMORY_MODERATE:內存不足,並且該進程在後臺進程列表的中部。
TRIM_MEMORY_BACKGROUND:內存不足,並且該進程是後臺進程。
TRIM_MEMORY_UI_HIDDEN:內存不足,並且該進程的UI已經不可見了。
onBind:綁定事務(Activity與Service通信時用到)
onUnbind:解除綁定
onRebind:重新綁定(再次綁定)

生命週期的流程這裏不做詳述了。
可參考其他博客

2.startService和bindService的區別
http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51471108

3.多進程下使用Service
多進程(IPC機制)有很多辦法可以實現:sharedpreferences、File、廣播、AIDL
選用AIDL基本可以滿足所有的業務需求,推薦使用AIDL

 <service android:name="com.augustine.service.WindowViewService"
            android:process=":windowService"/>
android:process 的作用就是開啓一個獨立的進 : 的後面是進程的名字            

注意:
1.新開進程後,Application會被多次執行(每啓用一個進程都會重新走Application)
2.static變量失效(都不在一個內存了,當然失效)
AIDL在AndroidStudio下使用,傳送門
http://blog.csdn.net/j275183662/article/details/52637160

4.Service中引用一個windowManager
Service中引用一個windowManager可以實現很多功能,比如:懸浮窗、提示框等等,當一個Service中持有一個windowManager當然可以幹很多事情了。。。
實現起來也是比較簡單,這裏貼出代碼

public class WindowViewService extends Service implements Runnable{

    private Thread pollThread;//循環線程

    private WindowManager windowManager;

    private WindowManager.LayoutParams layoutParams;

    private View contentView;

    @Override
    public void onCreate() {
        super.onCreate();
        init();
    }


    private void init(){
        contentView = View.inflate(getApplicationContext(), R.layout.view_window,null);
        pollThread = new Thread(this);
        windowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);
        layoutParams = new WindowManager.LayoutParams();
        layoutParams.gravity = Gravity.RIGHT;
        layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        layoutParams.format = PixelFormat.TRANSLUCENT;
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        layoutParams.width = 50;
        layoutParams.height = 55;
        windowManager.addView(contentView,layoutParams);
        pollThread.start();
        onTouch();
    }

    private int downX,downY;
    private int moveX,moveY;

    private void onTouch(){
        contentView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        downX = (int) event.getX();
                        downY = (int) event.getY();

                        break;
                    case MotionEvent.ACTION_MOVE:
                        moveX = (int) event.getX();
                        moveY = (int) event.getY();
                        layoutParams.x = moveX;
                        layoutParams.y = moveY;
                        windowManager.updateViewLayout(contentView,layoutParams);
                        break;
                    case MotionEvent.ACTION_UP:
                        downX = 0;
                        downY = 0;
                        moveX = 0;
                        moveY = 0;
                        break;
                }
                return true;
            }
        });
    }

    @Override
    public void onDestroy() {
        if(windowManager != null){
            windowManager.removeView(contentView);
        }
        if(pollThread != null){
            pollThread.destroy();
        }
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void run() {
        for(;;){
            Log.i("WindowViewService","線程");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

權限:
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.GET_TASKS" />

總結

靈活使用Service是必備技能,本篇就講述了Service的使用技巧,還是要多加練習

如有什麼問題,可以在博客下方留言

發佈了51 篇原創文章 · 獲贊 49 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章