当前位置:  编程技术>移动开发
本页文章导读:
    ▪Service bound(3)        Service bound(三) service 绑定有三种实现方式: 1. 直接继承Binder类实现。       条件: 同一应用,同一进程 2. 使用Messenger实现。       条件:要在不同的进程间通信,这种方式不用考虑线程.........
    ▪ NFC学习——NFC Enable 过程分析(1)        NFC学习——NFC Enable 过程分析(一)         拿到一台支持NFC手机或是平板设备时,在Settings->more可以看到NFC的enble,disnable的选项,还有android Beam这个东西。现在来分析NFC enable的过程   .........
    ▪ ListView的前后文长按事件       ListView的上下文长按事件在SetAdapter后加上:registerForContextMenu(listView);// 上下文菜单和listview结合的纽带 然后实现长按事件:其中:menuInfo.position是获取当前长按的是哪一项 // 上下文的点击事.........

[1]Service bound(3)
    来源: 互联网  发布时间: 2014-02-18
Service bound(三)

service 绑定有三种实现方式:

1. 直接继承Binder类实现。

      条件: 同一应用,同一进程

2. 使用Messenger实现。

      条件:要在不同的进程间通信,这种方式不用考虑线程安全性。(单线程操作时使用)

3. 使用AIDL实现。

      条件:要在不同的进程间通信,并且需要多线程处理。要考虑线程之间的安全性。


使用AIDL实现:

三大基本步骤

  • 创建.aidl文件
  • 实现接口
  • 公开接口


创建.aidl文件

  • 方法定义有0个或者多个参数,可以返回一个值或者是void.
  • 方法中不是基本类型的参数,需要在方法参数前面加入in , out or inout
  • 包含在.aidl中所有的注释在IBinder接口中都会生成(除了在import和package之前的注释)
  • 仅仅支持方法,不支持静态的成员变量。
package com.hualu.servicemy;

import com.hualu.servicemy.Book;

interface IRemoteService{
	
	int getPID() ;
	
	void basicInt(int i) ;
	
	void basicByte(byte b) ;
	
	void basicLong(long l) ;
	
	void basicDouble(double d) ;
	
	void basicFloat(float f) ;
	
	void basicString(String s) ;
	
	void basicBoolean(boolean b) ;
	
	void basicCharSequence(char c) ;
	
	void basicList(inout List<String> l) ;
	
	void basicMap(in Map m) ;
	
	Book getBook() ;
	
}


实现接口

  • 不能保证是从主线程里发起的调用,因此在使用的时候,需要考虑多线程启动和保证service运行时的线程安全性。
  • 默认情况,远程调用是同步的。
  • Service不会返回任何开发者自己抛出的异常到调用者。

package com.hualu.servicemy;

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

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;

public class RemoteService extends Service {

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

	private final IRemoteService.Stub iBinder = new IRemoteService.Stub() { //实现接口
		
		@Override
		public int getPID() throws RemoteException {
			return  Process.myPid();
		}
		
		@Override
		public Book getBook() throws RemoteException {
			Book book = new Book() ;
			book.setName("心善") ;
			return book;
		}
		
		@Override
		public void basicString(String s) throws RemoteException {
			System.out.println("string = "+s);
			
		}
		
		@Override
		public void basicMap(Map m) throws RemoteException {
			System.out.println("Map size = "+m.size());
			
		}
		
		@Override
		public void basicLong(long l) throws RemoteException {
			
			System.out.println("long = "+l);
		}
		
		@Override
		public void basicList(List<String> l) throws RemoteException {
			System.out.println("List size = "+l.size());
			
		}
		
		@Override
		public void basicInt(int i) throws RemoteException {
			
			System.out.println("int = "+i);
		}
		
		@Override
		public void basicFloat(float f) throws RemoteException {
			
			System.out.println("float = "+f);
		}
		
		@Override
		public void basicDouble(double d) throws RemoteException {
			
			System.out.println("double = "+d);
		}
		
		@Override
		public void basicCharSequence(char c) throws RemoteException {
			System.out.println("char = "+c);
			
		}
		
		@Override
		public void basicByte(byte b) throws RemoteException {
			
			
		}
		
		@Override
		public void basicBoolean(boolean b) throws RemoteException {
			
			
		}
	};
	
}


公开接口

package com.hualu.servicemy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;

import com.hualu.serviceexample.R;

public class RemoteActivity extends Activity {

	private IRemoteService  remoteService ;

	private boolean bindFlag = false ;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.remote_service) ;
		findViewById(R.id.remote).setOnClickListener(l) ;
	}
	
	private OnClickListener l = new OnClickListener(){

		@Override
		public void onClick(View v) {
			if(remoteService != null){
				try {
					remoteService.basicByte((byte)4) ;
					remoteService.basicBoolean(true) ;
					remoteService.basicInt(132) ;
					remoteService.basicLong(146) ;
					remoteService.basicFloat(83646.3f) ;
					remoteService.basicDouble(2.12) ;
					remoteService.basicString("remoteService") ;
					remoteService.basicCharSequence('r') ;
					List<String> l = new ArrayList<String>() ;
					l.add("Remote") ;
					l.add("Service") ;
					remoteService.basicList(l) ;
					Map<String,String> m = new HashMap<String,String>();
					m.put("a", "a") ;
					remoteService.basicMap(m) ;
					Book b = remoteService.getBook() ;
					System.out.println(b.getName());
				} catch (RemoteException e) {
					e.printStackTrace();
				}
				
			}
		}
		
	} ;
	
	@Override
	protected void onStart() {
		super.onStart();
		binderService() ;
	}
	
	@Override
	protected void onStop() {
		super.onStop();
		unBindService() ;
		remoteService = null ;
	}
	
	private ServiceConnection conn = new ServiceConnection(){ //公开接口

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			remoteService = IRemoteService.Stub.asInterface(service) ;
			bindFlag = true ;
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			remoteService = null ;
			bindFlag = false ;
		}
		
	} ;
	
	private void binderService(){
		bindService(new Intent(RemoteService.class.getName()), conn, Context.BIND_AUTO_CREATE) ;
	}
	
	private void unBindService(){
		unbindService(conn) ;
		bindFlag = false ;
		conn = null ;
	}
	
}






在aidl文件传递对象:

  • 创建实现Parcelable接口的类。
  • 实现 writeToParcel, 将对象目前的状态写到Pacel中。
  • 增加一个名字为CREATOR的静态的成员变量,这个CREATOR实现了Parcelable.Creator接口。
  • 最终,创建一个.aidl文件,声明你的parcelable类。
  • Book.aidl
    package com.hualu.servicemy;
    
    parcelable Book ;

    Book.java

    package com.hualu.servicemy;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class Book implements Parcelable {
    
    	private String name ;
    	
    	@Override
    	public int describeContents() {
    		return 0;
    	}
    	
    	public Book(){}
    	
        private Book(Parcel in) {
            readFromParcel(in);
        }
    
    	@Override
    	public void writeToParcel(Parcel dest, int flags) {
    		dest.writeString(name) ;
    	}
    
    	
    	public void readFromParcel(Parcel in){
    		name = in.readString() ;
    	}
    	
    	
    	public final static Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>(){
    
    		@Override
    		public Book createFromParcel(Parcel source) {
    			
    			return new Book(source);
    		}
    
    		@Override
    		public Book[] newArray(int size) {
    			
    			return new Book[size];
    		}
    		
    	} ;
    	
    	public void setName(String name){
    		this.name = name ;
    	}
    	
    	public String getName(){
    		return this.name ;
    	}
    	
    }
    

    Layout文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical" >
    
        <Button
            android:id="@+id/remote"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/get_remote_data" />
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/remote_service" />
    
    </LinearLayout>

    Manifest文件中定义的Activity和service:

    <activity android:name="com.hualu.servicemy.RemoteActivity">
    			<intent-filter>
    				<action android:name="android.intent.action.MAIN"></action>
    				<category android:name="android.intent.category.LAUNCHER"></category>			
    			</intent-filter>
    		</activity>
            <service android:name="com.hualu.servicemy.RemoteService">
                <intent-filter >
                    <action android:name="com.hualu.servicemy.RemoteService"/>
                </intent-filter>
            </service>


    运行结果:




    公开接口

        
    [2] NFC学习——NFC Enable 过程分析(1)
        来源: 互联网  发布时间: 2014-02-18
    NFC学习——NFC Enable 过程分析(一)

             拿到一台支持NFC手机或是平板设备时,在Settings->more可以看到NFC的enble,disnable的选项,还有android Beam这个东西。现在来分析NFC enable的过程   

              wireless_settings.xml 在Settings配置了NFC功能项:

        <CheckBoxPreference
            android:key="toggle_nfc"
            android:title="@string/nfc_quick_toggle_title"
            android:summary="@string/nfc_quick_toggle_summary"
            android:persistent="false" />
    
        <PreferenceScreen
            android:fragment="com.android.settings.nfc.AndroidBeam"
            android:key="android_beam_settings"
            android:title="@string/android_beam_settings_title" />
             xml配置的对应处理代码在:packages/apps/Settings/src/com/android/settings/WirelessSettings.java

    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            addPreferencesFromResource(R.xml.wireless_settings); 
            CheckBoxPreference nfc = (CheckBoxPreference) findPreference(KEY_TOGGLE_NFC);
            PreferenceScreen androidBeam = (PreferenceScreen) findPreference(KEY_ANDROID_BEAM_SETTINGS); 
    
            //setp1:获取NfcEnable的实例
            mNfcEnabler = new NfcEnabler(activity, nfc, androidBeam); 
            ......
    
            // Remove NFC if its not available            
            //setp2:获取NfcAdapter实例,查看NFC功能是否可能
            mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);
            if (mNfcAdapter == null) {
                getPreferenceScreen().removePreference(nfc);
                getPreferenceScreen().removePreference(androidBeam);
                mNfcEnabler = null;
            } 
     }
    

    setp1:NFcEnable实例 packages/apps/Settings/src/com/android/settings/nfc/NfcEnabler.java 实现Preference.OnPreferenceChangeListener接口监听NFC Enable,disnable事件

    public boolean onPreferenceChange(Preference preference, Object value) {
            // Turn NFC on/off
    
            final boolean desiredState = (Boolean) value;
            mCheckbox.setEnabled(false);
    
            if (desiredState) {           
               //setp3:用setp2一样的方式获取NfcAdapter实例出来nfc enable
                mNfcAdapter.enable();
            } else {
                mNfcAdapter.disable();
            }
    
            return false;
        }
             同时也是在这个NfcEnabler.java中处理了,Nfc enble,diable时,android beam的灰亮显示问题。

    Setp2:现在所有的分析点集中到了NfcAdaper这个类中,首先来看下NfcAdapter实例的获取

    源代码的路径:frameworks/base/core/java/android/nfc/NfcAdapter.java

        public static NfcAdapter getDefaultAdapter(Context context) { 
              ......  
    
           /* use getSystemService() for consistency */
            NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
            if (manager == null) {
                // NFC not available
                return null;
            }          
            //setp2-1
            return manager.getDefaultAdapter();
        }
    在NFC学习——NfcService 启动过程分析  文章中NfcService的onCreate()方法中有如下code:

     //把mNfcAdapter 作为Service 添加到系统服务中,ServiceManager.getService("nfc")可以获取到binder 
     ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 
    NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);获取到的Service 就是之前add的service。

               Setp2-1:manager.getDefaultAdapter其实饶了一圈又回到NfcAdapter类中获取NfcAdapter实例,具体看下面code

    code路径:frameworks/base/core/java/android/nfc/NfcManager.java

    public NfcAdapter getDefaultAdapter() {
            return mAdapter;
        }
    这个mAdaper如何来的呢?

        public NfcManager(Context context) {
            NfcAdapter adapter;
            ......
             try {
                adapter = NfcAdapter.getNfcAdapter(context);
            } catch (UnsupportedOperationException e) {
                adapter = null;
            }
            mAdapter = adapter;
        }
    最终又回到NfcAdapter.gerNfcAdapter(context)这个方法上获取实例,具体来分析:

      public static synchronized NfcAdapter getNfcAdapter(Context context) {
            if (!sIsInitialized) {
                ......
                //setp2-2:应用INfcAdapter.aidl和NfcService通信 
                sService = getServiceInterface();
                if (sService == null) {
                    Log.e(TAG, "could not retrieve NFC service");
                    throw new UnsupportedOperationException();
                }
                try { 
                    //note2
                    sTagService = sService.getNfcTagInterface();
                } catch (RemoteException e) {
                    Log.e(TAG, "could not retrieve NFC Tag service");
                    throw new UnsupportedOperationException();
                }
    
                sIsInitialized = true;
            }
            if (context == null) {
                if (sNullContextNfcAdapter == null) {
                    sNullContextNfcAdapter = new NfcAdapter(null);
                }
                return sNullContextNfcAdapter;
            }              
            //sNFcAdapter 是个HashMap,从中取出之前创建的NfcAdapter实例
            NfcAdapter adapter = sNfcAdapters.get(context);
            if (adapter == null) {
                adapter = new NfcAdapter(context);
                sNfcAdapters.put(context, adapter);
            }
            return adapter;
        }
              Setp2-2:应用INfcAdapter.aidl和NfcService通信 ,INfcAdapter的方法都在NfcService的内部类NfcAdapterService中实现。

        /** get handle to NFC service interface */
        private static INfcAdapter getServiceInterface() {
            /* get a handle to NFC service */
            IBinder b = ServiceManager.getService("nfc");
            if (b == null) {
                return null;
            }
            return INfcAdapter.Stub.asInterface(b);
        }
    现在Setp2的NfcAdapter已经得到了它的实例,接下来就Setp3,NfcAdapter.enable()和NfcAdapter.disable():

        public boolean enable() {
            try { 
                //从setp2-2可以知道sService.enable()通过NfcAdapterService来实现的
                return sService.enable();
            } catch (RemoteException e) {
                attemptDeadServiceRecovery(e);
                return false;
            }
        }
    接下来看NfcAdapterService extends INfcAdapter.Stub 中的enable()方法:

    public boolean enable() throws RemoteException {            
          //Question 1:
          NfcService.enforceAdminPerm(mContext);
          //把NFC 打开状态写到SharedPreferences中保存起来
          saveNfcOnSetting(true);             
          ......   
          //AsyncTash后台处理NFC的打开      
          new EnableDisableTask().execute(TASK_ENABLE);
          return true;
    }

    上面code 提到一个Question 1,其实它就是给NFC 赋予一个写的权限。

    EnableDisableTask 在doInBackground中调用enableInternal();来处理NFC  turn on。

     boolean enableInternal() { 
                //logcat 信息可以看到的log信息
                Log.i(TAG, "Enabling NFC");
                updateState(NfcAdapter.STATE_TURNING_ON);                   
                //setp3-1:调用jni initialize做init相关的动作
                if (!mDeviceHost.initialize()) {
                    Log.w(TAG, "Error enabling NFC");
                    updateState(NfcAdapter.STATE_OFF);
                    return false;
                }
                synchronized(NfcService.this) {
                    mObjectMap.clear(); 
                    //setp 3-2:开启一些循环监听的线程服务
                    mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
                    updateState(NfcAdapter.STATE_ON);
                }
    
                initSoundPool();
    
                /* Start polling loop */
                applyRouting(true);
                return true;
            }

    setp3-1:initialize()对应的是在NativeNfcManager.java 中initialize()实现的,NativeNfcManager.initialize()直接调用的是jni方法doInitialize(),doInitialize()对应的在jni的方法:com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o),这部分将在NFC学习——NFC Enable 过程分析(二)   分析。       

    setp3-2:这一部分将在NFC学习——NFC Enable 过程分析(三)    分析   

    以上部分的分析配合下面这张图就更清晰了

    以上图片来自:NFC framework introduce(一)


        
    [3] ListView的前后文长按事件
        来源: 互联网  发布时间: 2014-02-18
    ListView的上下文长按事件

    在SetAdapter后加上:registerForContextMenu(listView);// 上下文菜单和listview结合的纽带

    然后实现长按事件:其中:menuInfo.position是获取当前长按的是哪一项

     // 上下文的点击事件
     @Override
     public boolean onMenuItemSelected(int featureId, MenuItem item) {
      if (item.getMenuInfo() instanceof AdapterContextMenuInfo) {
       AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item
         .getMenuInfo();
       // 处理菜单的点击事件
       switch (item.getItemId()) {
    其中:menuInfo.position能获取当前长按的item                                                                                          case 1:
    
    
        break;
       case 2:
        Toast.makeText(this, "查看功能" + menuInfo.position,
          Toast.LENGTH_SHORT).show();
        break;
       case 3:
       
        break;
       case 4:
        Toast.makeText(this, "取消功能" + menuInfo.position,
          Toast.LENGTH_SHORT).show();
        break;
       }
      }
      return super.onContextItemSelected(item);
     }
    


     

     


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3