日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

反射在java中的应用_java反射机制在项目中的运用

發布時間:2023/12/19 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 反射在java中的应用_java反射机制在项目中的运用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

定義:Reflection是java開發語言特性之一,它允許運行中的java程序對自身進行檢測,自審,并能操作程序內部的屬性和方法,Reflection是java被視為動態語言關鍵之一。允許程序從執行期的Reflection APIS取得任何已知名稱的class內部信息,包含packages、type parameters、superclass、implement Interfaces、inner classes、outer class、fields、methods、constructors、modifiers,并可在執行期間執行instance,更變field內容,喚醒method。

反射過程中常用的類:

java反射所需要的類并不多,他們分別是:Class、Constructor、Object、Method、Field。

Class類:每個class都有一個相應的Class對象。也就是說,當我們編寫一個類,編譯完成后,在生成的.class文件中,就會產生一個Class對象,在運行期間如果我們需要產生某個類的對象,JVM就會檢測該類型的Class對象是否已經被加載,如果沒有被加載,則虛擬機會根據類名稱找到并加載相對應的.class文件,一旦某個類型的Class對象加載到內存中,就可以用它來產生相應的對象。

Constructor類:封裝了反射類的構造方法,提供該類單個構造方法和訪問權限信息。

Object類:每個類都使用Object作為超類,所有的對象都實現這個類的方法。

Method類:提供有關類或者接口單獨某個方法的信息,以及動態訪問權限,所反映的方法可能是類方法或者實例方法以及抽象方法。

Field類:提供有關類或者結構單獨屬性的信息,以及動態訪問權限,所反映的屬性可能是類屬性或者實例屬性。

項目中的實際運用:上次在講述Android AIDL IPC通信的時候提到過,基于AIDL實現客戶端被注冊的view通過反射以及服務端傳過來的數據達成一個交互過程。實現圖片文字的顯示過程。

客戶端調用:首先:我們需要實現我們要注冊的MyImageView,繼承自ImageView,主要用來圖片顯示。

package com.zlc.aidl.client;

import android.content.Context;

import android.graphics.Bitmap;

import android.widget.ImageView;

public class MyImageView extends ImageView{

public MyImageView(Context context) {

super(context);

}

@Override

public void setImageBitmap(Bitmap bm) {

// TODO Auto-generated method stub

super.setImageBitmap(bm);

}

}

然后:我們需要反射的工具類ReflectionInvoke.java,用來反射調用注冊view對象里面的方法,通過服務端傳過來的參數和對應方法名來進行反射調用。在工具類中包含一個InvokeKey的內部類,主要用來標示一個對象的某個方法,并保存到工具類集合里面,下次調用的時候不需要再進行尋找method的過程,直接invoke反射調用就行。

package com.zlc.aidl.client;

import java.lang.ref.WeakReference;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.HashMap;

import java.util.List;

import android.util.Log;

public class ReflectionInvoke {

public static HashMap> reflections = new HashMap>();

private Method method;

private Class> clazz;

private Class> parameterClasses[];

static class InvokeKey {

String className;

String methodName;

String[] paramsClassName;

public InvokeKey(String className, String methodName, String[] paramsClassName) {

this.className = className;

this.methodName = methodName;

this.paramsClassName = paramsClassName;

}

@Override

public int hashCode() {

// TODO Auto-generated method stub

int ret = className.hashCode();

ret = methodName.hashCode() + ret * 10;

for (int i = 0; i < paramsClassName.length; i++) {

ret = paramsClassName[i].hashCode() + ret * 10;

}

return ret;

}

@Override

public boolean equals(Object o) {

if (o instanceof InvokeKey) {

InvokeKey key = (InvokeKey) o;

if (!key.className.equals(className) || !key.methodName.equals(methodName)

|| key.paramsClassName.length != paramsClassName.length) {

return false;

} else {

for (int i = 0; i < paramsClassName.length; i++) {

if (!key.paramsClassName[i].equals(paramsClassName[i]))

return false;

}

return true;

}

}

return false;

}

}

Class> classForNameX(String name) throws Exception {

if ("int".equals(name))

return int.class;

else if ("char".equals(name))

return char.class;

else if ("short".equals(name))

return short.class;

else if ("byte".equals(name))

return byte.class;

else if ("long".equals(name))

return long.class;

else if ("float".equals(name))

return float.class;

else if ("double".equals(name))

return double.class;

else if ("boolean".equals(name))

return boolean.class;

return Class.forName(name);

}

private ReflectionInvoke(InvokeKey key) throws Exception {

clazz = Class.forName(key.className);

parameterClasses = new Class[key.paramsClassName.length];

for (int i = 0; i < parameterClasses.length; i++) {

parameterClasses[i] = classForNameX(key.paramsClassName[i]);

}

method = clazz.getMethod(key.methodName, parameterClasses);

}

public static ReflectionInvoke getInvoker(String className, String methodName,

List argsClassName) {

String[] arrayarges = new String[argsClassName.size()];

argsClassName.toArray(arrayarges);

return getInvoker(className, methodName, arrayarges);

}

public static ReflectionInvoke getInvoker(String className, String methodName, String... args) {

ReflectionInvoke invoke = null;

synchronized (reflections) {

try {

InvokeKey key = new InvokeKey(className, methodName, args);

WeakReference w = reflections.get(key);

if (w == null ? true : (invoke = w.get()) == null) {

invoke = new ReflectionInvoke(key);

reflections.put(key, new WeakReference(invoke));

}

} catch (Exception e) {

e.printStackTrace();

}

}

return invoke;

}

public Object invokeNoException(Object obj, Object... args) {

try {

return method.invoke(obj, args);

} catch (Exception e) {

Log.d("Exception", "invoke error");

}

return null;

}

public Object invoke(Object obj, Object... args) throws IllegalArgumentException,

IllegalAccessException, InvocationTargetException {

Log.d("ReflectionInvoke", "invoke invoke invoke");

return method.invoke(obj, args);

}

}

其次:需要準備一個實現parcelable的對象,用來在兩個進程之間傳遞方法名、方法參數等信息。

package com.zlc.aidl;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import android.graphics.Bitmap;

import android.os.Parcel;

import android.os.ParcelFileDescriptor;

import android.os.Parcelable;

public class JsonReflectionInvokParcelable implements Parcelable{

public String objectId;

public String methodname;

public List argsClassName;

public List argsVaule;

@Override

public int describeContents() {

return 0;

}

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(objectId);

dest.writeString(methodname);

dest.writeList(argsClassName);

dest.writeList(argsVaule);

}

public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {

public JsonReflectionInvokParcelable createFromParcel(Parcel in) {

JsonReflectionInvokParcelable tp = new JsonReflectionInvokParcelable();

tp.objectId = in.readString();

tp.methodname = in.readString();

tp.argsClassName = new ArrayList();

in.readList(tp.argsClassName, null);

tp.argsVaule = new ArrayList();

in.readList(tp.argsVaule, null);

return tp;

}

public JsonReflectionInvokParcelable[] newArray(int size) {

return new JsonReflectionInvokParcelable[size];

}

};

public void clean() {

for (Object o : argsVaule) {

try {

if (o instanceof ParcelFileDescriptor)

((ParcelFileDescriptor) o).close();

else if (o instanceof Bitmap)

((Bitmap) o).recycle();

} catch (IOException e) {

}

}

}

}

服務端調用

再次:服務端發送數據之前檢測并且封裝參數的類型

……

public void callReflection(String json, String objId, String method,

Object ...args) throws RemoteException {

JsonReflectionInvokParcelable p = new JsonReflectionInvokParcelable();

p.objectId = objId;

p.methodname = method;

p.argsClassName = new ArrayList();

p.argsVaule = new ArrayList();

Log.d(TAG, "callReflection222 json=" + json);

for (int i = 0; i < args.length; i++) {

Object o = args[i];

@SuppressWarnings("rawtypes")

Class clazz = o.getClass();

if (clazz.isPrimitive() || o instanceof Parcelable || o instanceof String

|| o instanceof Integer || o instanceof Short || o instanceof Float

|| o instanceof Double || o instanceof Character) {

p.argsClassName.add(clazz.getCanonicalName());

p.argsVaule.add(o);

} else {

throw new RuntimeException("args only support primitives and String");

}

}

callback.onReflectionCallback(p, json);

Log.d(TAG, "callReflection222 end json=" + json);

}

……

最后:從服務端調用客戶端注冊view的某個指定方法

private final IMyAidlService.Stub mBinder = new IMyAidlService.Stub() {

@Override

public void registerClient(AIDLCallback cb) throws RemoteException {

Log.d(TAG, "registerClient");

callback = cb;

Bitmap bmp = BitmapFactory.decodeFile("/data/data/com.zlc.aidl.server/files/1.jpg");

callReflection("just for test","myImageView","setImageBitmap",bmp);

cb.asBinder().linkToDeath(new DeathRecipient() {

@Override

public void binderDied() {

// TODO Auto-generated method stub

try {

Log.i(TAG, "[ServiceAIDLImpl]binderDied.");

} catch (Throwable e) {

}

}

}, 0);

}

};

具體反射的其他一些用途和使用方式,大家可以去問問度娘和谷哥,這有個例子講述了大部分使用方法。

最后附上反射使用實例的源碼,圖片自己下載一張存放到/data/data/com.zlc.aidl.server/files/目錄下,如果沒有files目錄,可通過代碼創建或者通過linux命令創建。

總結

以上是生活随笔為你收集整理的反射在java中的应用_java反射机制在项目中的运用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。