public class SmsManager { private static SmsManager[] sInstance; private int mPhoneId = -1; static{ sInstance = new SmsManager[2]; for(int i =0; i<2; i++){ sInstance[0] = new SmsManager(i); Log.d("jimwind","SmsManager static "+i); } } private SmsManager(int phoneId){ mPhoneId = phoneId; } public static SmsManager getDefault(int phoneId){ if(phoneId > 1) throw new IllegalArgumentException("phoneId exceeds phoneCount"); Log.d("jimwind","SmsManager getDefault"); return sInstance[phoneId]; } }
使用類時,調用SmsManager.getDefault(0);先加載類,運行static代碼段,而後運行getDefault(); java
TelephonyManager也是相似的方式。android
---------------------------------------------------------------------------------------------express
ITelephony.Stub.asInterfaceapache
ITelephony.aidl在編譯時不使用,而是使用用Android的SDK中提供了一個aidl工具生成的ITelephony.javaapp
ITelephony.java 就至關於兩個進程間的通訊協議。less
實驗:ide
/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mi.telephony; /** * Interface used to interact with the phone. Mostly this is used by the * TelephonyManager class. A few places are still using this directly. * Please clean them up if possible and use TelephonyManager insteadl. * * {@hide} */ interface ITelephony { /** * Dial a number. This doesn't place the call. It displays * the Dialer screen. * @param number the number to be dialed. If null, this * would display the Dialer screen with no number pre-filled. */ void dial(String number); }
放在com/mi/telephony下面函數
>aidl com\mi\telephony\ITelephony.aidl工具
生成ITelephony.javaui
/* * This file is auto-generated. DO NOT MODIFY. * Original file: com\\mi\\telephony\\ITelephony.aidl */ package com.mi.telephony; /** * Interface used to interact with the phone. Mostly this is used by the * TelephonyManager class. A few places are still using this directly. * Please clean them up if possible and use TelephonyManager insteadl. * * {@hide} */ public interface ITelephony extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.mi.telephony.ITelephony { private static final java.lang.String DESCRIPTOR = "com.mi.telephony.ITelephony"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.mi.telephony.ITelephony interface, * generating a proxy if needed. */ public static com.mi.telephony.ITelephony asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.mi.telephony.ITelephony))) { return ((com.mi.telephony.ITelephony)iin); } return new com.mi.telephony.ITelephony.Stub.Proxy(obj); } public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_dial: { data.enforceInterface(DESCRIPTOR); java.lang.String _arg0; _arg0 = data.readString(); this.dial(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.mi.telephony.ITelephony { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /** * Dial a number. This doesn't place the call. It displays * the Dialer screen. * @param number the number to be dialed. If null, this * would display the Dialer screen with no number pre-filled. */ public void dial(java.lang.String number) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(number); mRemote.transact(Stub.TRANSACTION_dial, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_dial = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } /** * Dial a number. This doesn't place the call. It displays * the Dialer screen. * @param number the number to be dialed. If null, this * would display the Dialer screen with no number pre-filled. */ public void dial(java.lang.String number) throws android.os.RemoteException; }
---------------------------------------------------------------------------------------------
android 關於接口的使用:
以Mms中ConversationList與DraftCache.OnDraftChangedListener接口調用關係分析
一、 ConversationList implements DraftCache.OnDraftChangedListener
實現接口中的函數onDraftChanged
二、先查看在ConversationList類中,對類DraftCache的使用
列出:
DraftCache.getInstance().addOnDraftChangedListener(this);
DraftCache.getInstance().refresh();
DraftCache.getInstance().setDraftState();
DraftCache.getInstance().getSavingDraft());
DraftCache.getInstance().removeOnDraftChangedListener(this);
三、再查看在DraftCache類中,對接口OnDraftChangedListener方法onDraftChanged中的調用。
列出:
refresh() -> private synchronized void rebuildCache()->onDraftChanged
public synchronized void setDraftState() -> onDraftChanged
這裏,onDraftChanged是接口使用者本身實現,調用關係由定義接口的類肯定。(若是接口使用者直接調用就沒有意義了)
-----------------------------------------------------------------------------------------
類AsyncQueryHandler 的使用