android ServiceManager

之前使用Android綁定服務(wù)的功能跳昼,每次使用的時候都不是很方便,因為是異步的敲霍,代碼也比較多俊马,我現(xiàn)在想用同步的方式去調(diào)用服務(wù)的方法,一是代碼少肩杈,二是調(diào)用方便柴我。

之前嘗試先綁定服務(wù),然后保留得到的服務(wù)接口對象扩然,可是事與愿違艘儒,服務(wù)接口對象永不了多久就斷開連接了。翻看了TelephonyManager代碼夫偶,里面保存IBinder對象界睁,于是就嘗試保存服務(wù)的IBinder對象,需要調(diào)用服務(wù)的方法時通過IBinder對象去獲取服務(wù)對象接口兵拢,測試之后沒問題翻斟。

ServiceManager

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;

import java.util.Hashtable;
import java.util.List;
import java.util.Map;

/**
 * 本地服務(wù)和遠程服務(wù)的管理器。
 * 更加便捷的調(diào)用服務(wù)说铃,以一種同步的方法去調(diào)用服務(wù)方法访惜,
 * 調(diào)用之前需要先做好前提工作,之后就可以以同步的方式去調(diào)用服務(wù)方法
 * Created by 徐仕海 on 2017/5/13.
 */

public class ServiceManager {

    private static ServiceManager instance;

    /**
     * 線程安全的到懶漢單例模式
     *
     * @return
     */
    public static ServiceManager getDefault() {
        ServiceManager tmp = instance;
        if (tmp == null) {
            synchronized (ServiceManager.class) {
                instance = tmp = new ServiceManager();
            }
        }
        return tmp;
    }

    private Map<String, IBinder> cache = new Hashtable<>();//線程安全的Map


    /**
     * 添加動作為action的服務(wù)(IBinder)到cache中
     * 添加成功后便可以一直以同步的方法去調(diào)用服務(wù)方法截汪。
     * 保存的IBinder對象不會像保存服務(wù)的接口對象會常常死掉疾牲。
     * 以后每次使用服務(wù)的方法時聲稱一次服務(wù)的接口就可以了,方便又安全衙解。
     *
     * @param context
     * @param action
     */
    public void addService(final Context context, final String action) {
        if (isIBinderEnabled(action))
            return;
        Intent intent = getExplicitIntent(context, new Intent(action));
if (intent == null)
            return;
        boolean ret = context.bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                cache.put(action, service);
                context.unbindService(this);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
            }
        }, Context.BIND_AUTO_CREATE);
    }

    /**
     * 獲取顯式的Intent,android5.0之后綁定服務(wù)只能是顯式Intent不能用隱式Intent.
     *
     * @param context
     * @param implicitIntent
     * @return
     */
    private Intent getExplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }
        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);
        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);
        // Set the component to be explicit
        explicitIntent.setComponent(component);
        return explicitIntent;
    }

    /**
     * 獲取action對應(yīng)的服務(wù)的IBinder對象阳柔,這種對象可以用來生成可以直接使用的服務(wù)接口對象
     *
     * @param action
     * @return
     */
    public IBinder getService(String action) {
        return cache.get(action);
    }

    /**
     * 判斷action對應(yīng)的遠程服務(wù)的IBinder是否可用
     *
     * @param action
     * @return
     */
    public boolean isIBinderEnabled(String action) {
        IBinder localBinder = getService(action);
        return localBinder != null && localBinder.isBinderAlive();
    }

}

DeviceManager

import android.content.Context;

import com.math.IMathAidlInterface;

/**
 * Created by Administrator on 2017/5/13.
 */

public class DeviceManager extends ServiceManager {

    private static DeviceManager instance;

    /**
     * 線程安全的到懶漢單例模式
     *
     * @return
     */
    public static DeviceManager getDefault() {
        DeviceManager tmp = instance;
        if (tmp == null) {
            synchronized (DeviceManager.class) {
                instance = tmp = new DeviceManager();
            }
        }
        return tmp;
    }


/**********************************************************************************************************************/

    final String ACTION_MATH = "com.math";

    public void addMathService(Context context) {
        addService(context, ACTION_MATH);
    }

    /**
     * 將action對應(yīng)的遠程服務(wù)轉(zhuǎn)換成可用的IInterface
     *
     * @return
     */
    public IMathAidlInterface getIMath() {
        return IMathAidlInterface.Stub.asInterface(getService(ACTION_MATH));
    }
}

使用方法

findViewById(R.id.tv_name).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IMathAidlInterface iMathAidlInterface = DeviceManager.getDefault().getIMath();
                try {
                    Toast.makeText(MainActivity.this, "" + iMathAidlInterface.add(1, 33), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
DeviceManager.getDefault().addMathService(this);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蚓峦,隨后出現(xiàn)的幾起案子舌剂,更是在濱河造成了極大的恐慌济锄,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件霍转,死亡現(xiàn)場離奇詭異荐绝,居然都是意外死亡,警方通過查閱死者的電腦和手機避消,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門低滩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岩喷,你說我怎么就攤上這事恕沫。” “怎么了纱意?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵婶溯,是天一觀的道長。 經(jīng)常有香客問我偷霉,道長迄委,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任类少,我火速辦了婚禮叙身,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瞒滴。我一直安慰自己曲梗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布妓忍。 她就那樣靜靜地躺著虏两,像睡著了一般。 火紅的嫁衣襯著肌膚如雪世剖。 梳的紋絲不亂的頭發(fā)上定罢,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天,我揣著相機與錄音旁瘫,去河邊找鬼祖凫。 笑死,一個胖子當(dāng)著我的面吹牛酬凳,可吹牛的內(nèi)容都是我干的惠况。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼宁仔,長吁一口氣:“原來是場噩夢啊……” “哼稠屠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤权埠,失蹤者是張志新(化名)和其女友劉穎榨了,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攘蔽,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡龙屉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了满俗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片转捕。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖漫雷,靈堂內(nèi)的尸體忽然破棺而出瓜富,到底是詐尸還是另有隱情,我是刑警寧澤降盹,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站谤辜,受9級特大地震影響蓄坏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丑念,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一涡戳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脯倚,春花似錦渔彰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至植榕,卻和暖如春再沧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尊残。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工炒瘸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寝衫。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓顷扩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親慰毅。 傳聞我的和親對象是個殘疾皇子隘截,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容