jQuery鼠标指针特效

关于Android 控件没有动态设置界面效果时,如何处理

关于Android 控件没有动态设置界面效果时,如何处理

例子:android:scrollbarThumbVertical 动态设置 -->listView

如果控件只有静态xml界面的设置,没有动态设置时,需要去查看安卓控件的源码,看该控件继承了那个父控件的方法,然后利用反射调用!
不同的Android 版本,源码可能不同!

Android 11.0

View.java

 /**
     * Defines the vertical scrollbar thumb drawable
     * @attr ref android.R.styleable#View_scrollbarThumbVertical
     *
     * @see #awakenScrollBars(int)
     * @see #isVerticalScrollBarEnabled()
     * @see #setVerticalScrollBarEnabled(boolean)
     */
    public void setVerticalScrollbarThumbDrawable(@Nullable Drawable drawable) {
        initializeScrollBarDrawable();
        mScrollCache.scrollBar.setVerticalThumbDrawable(drawable);
    }


<ListView
        android:id="@+id/list"
        android:layout_width="wrap_content"
        android:layout_height="250dp"
        android:entries="@array/array_adapter_strs" />

//ListView 动态改变scrollbarThumbVertical
private void changeViewProgress(){
        try {
            Class three = Class.forName("android.view.View");
            Method method_2 = three.getMethod("setVerticalScrollbarThumbDrawable", Drawable.class);
            method_2.invoke(listView,getDrawable(R.drawable.title_music));
        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

参考链接:
动态设置
java反射

java反射调用Android系统服务

Android 源码里的一些反射应用
+    //add text
+    private void setProperty(String key, String value){
+        try {
+            Class<?> c =  Class.forName("android.os.SystemProperties");
+            Method method = c.getMethod("set",String.class,String.class);
+            method.invoke(c,key,value);
+        }catch (Exception e){
+            Log.d(TAG,"xxxxxxxxxx");
+        }
+    }
+    //add text

public static String getSystemProperty(String property, String defaultValue) {
        try {
            Class clazz = Class.forName("android.os.SystemProperties");
            Method getter = clazz.getDeclaredMethod("get", String.class);
            String value = (String) getter.invoke(null, property);
            if (!TextUtils.isEmpty(value)) {
                return value;
            }
        } catch (Exception e) {
            Log.d(TAG, "Unable to read system properties");
        }
        return defaultValue;
    }


如何反射系统服务类的函数?

PowerManager类并没有提供关机的shutdown接口,而是通过IBinder这种Android中特有的通信模式,与PowerManagerService 类进行通信.
PowerManagerService是PowerManager 类中定义的接口的具体实现,并进一步调用Power 类来与下一层进行通信.
在PowerManagerService实现了shutdown接口,power服务实现了关机功能.
PowerManager的实现通过IPowerManager来调用Power服务的接口,
IPowerManager是AIDL文件自动生成的类,便于远程通信.
IPowerManage.aidl文件目录:framework/base/core/java/android/os/IPowerManage.aidl

IPowerManager实现了shutdown接口.所以,如果我们能够获得Power服务的IBinder,通过反射调用shutdown方法就能实现关机功能.
需要注意的是,ServiceManager管理着系统的服务程序,它保存着所有服务的IBinder,通过服务名就能获取到这个服务的IBinder.
但ServiceManager这个类也是HIDE的,也需要反射进行调用两次.
通过两次反射调用,就能调用power服务实现的关机功能.

实际使用需要:android:sharedUserId="android.uid.system" ,系统app和权限

//关机
 try {
 
	 //获得ServiceManager类
	 Class<?> ServiceManager = Class.forName("android.os.ServiceManager");
	 
	 //获得ServiceManager的getService方法
	 Method getService = ServiceManager.getMethod("getService", java.lang.String.class);
	 
	 //调用getService获取RemoteService
	 Object oRemoteService = getService.invoke(null,Context.POWER_SERVICE);
	 
	 //获得IPowerManager.Stub类
	 Class<?> cStub = Class.forName("android.os.IPowerManager$Stub");
	 //获得asInterface方法
	 Method asInterface = cStub.getMethod("asInterface", android.os.IBinder.class);
	 //调用asInterface方法获取IPowerManager对象
	 Object oIPowerManager = asInterface.invoke(null, oRemoteService);
	 //获得shutdown()方法
	 Method shutdown = oIPowerManager.getClass().getMethod("shutdown",boolean.class,boolean.class);
	 //调用shutdown()方法
	 shutdown.invoke(oIPowerManager,false,true);           
 
   } catch (Exception e) {         
	   Log.e(TAG, e.toString(), e);        
   }
   
 //U盘挂载
  public static void mountDisk() {
        Log.v(TAG, "mountDisk begin");
        try {
            Class<?> clz = Class.forName("android.os.ServiceManager");
            Method getService = clz.getMethod("getService", String.class);
            Object powerService = getService.invoke(null, "mount");
 
            Class<?> cStub = Class.forName("android.os.storage.IStorageManager$Stub");
            Method asInterface = cStub.getMethod("asInterface", IBinder.class);
            Object IPowerManager = asInterface.invoke(null, powerService);
            Method shutDown = IPowerManager.getClass().getMethod("mount", String.class);
            shutDown.invoke(IPowerManager, "public:8,1");
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.v(TAG, "mountDisk end");
    }
 
 
    public static void unmountDisk() {
        Log.v(TAG, "unmountDisk begin");
        try {
            Class<?> clz = Class.forName("android.os.ServiceManager");
            Method getService = clz.getMethod("getService", String.class);
            Object powerService = getService.invoke(null, "mount");
 
            Class<?> cStub = Class.forName("android.os.storage.IStorageManager$Stub");
            Method asInterface = cStub.getMethod("asInterface", IBinder.class);
            Object IPowerManager = asInterface.invoke(null, powerService);
            Method shutDown = IPowerManager.getClass().getMethod("unmount", String.class);
            shutDown.invoke(IPowerManager, "public:8,1");
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.v(TAG, "unmountDisk end");
    }
 
 
    public static boolean isUsbDiskMounted() {
        String mount = SystemPropertiesUtil.getProperty("vold.usbdisk.state", "");
        return "mounted".equals(mount);
    } 
系统测试,不反射使用
IPowerManager mPowerManager;
PowerManager mPm;
PowerManager.WakeLock mProx;

    protected Test[] tests() {
        mPowerManager = IPowerManager.Stub.asInterface(ServiceManager.getService("power"));
        mPm = (PowerManager)getSystemService("power");
        mProx = mPm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "PowerTest-prox");
        
        return mTests;
    }

工具类

/**
 * 反射工具
 *
 * @author GaoFei
 */
public class ReflectUtils {
    private static final String TAG = "ReflectUtils";

    public static void setFieldValue(Object targetObject, String filedName, Object filedvalue) {
        try {
            Field field = targetObject.getClass().getDeclaredField(filedName);
            field.setAccessible(true);
            field.set(targetObject, filedvalue);
        } catch (Exception e) {
            Log.e(TAG, "setFieldValue->filedName:" + filedName);
            Log.e(TAG, "setFieldValue->value:" + filedvalue);
            Log.e(TAG, "setFieldValue->exception:" + e);
        }

    }

    public static Object getFieldValue(Object targetObject, String filedName) {
        try {
            Field field = targetObject.getClass().getDeclaredField(filedName);
            field.setAccessible(true);
            return field.get(targetObject);
        } catch (Exception e) {
            Log.e(TAG, "getFieldValue->filedName:" + filedName);
            Log.e(TAG, "getFieldValue->exception:" + e);
        }
        return null;
    }

    public static Object invokeMethod(Object object, String methodName, Class<?>[] paramTypes, Object[] values) {
        try {
            Method method = object.getClass().getDeclaredMethod(methodName, paramTypes);
            method.setAccessible(true);
            return method.invoke(object, values);
            //return method.invoke(object, paramTypes);
        } catch (Exception e) {
            Log.e(TAG, "invokeMethod->methodName:" + methodName);
            Log.e(TAG, "invokeMethod->exception:" + e);

        }
        return null;
    }

    public static Object invokeMethodNoParameter(Object object, String methodName) {
        try {
            Method method = object.getClass().getDeclaredMethod(methodName);
            method.setAccessible(true);
            return method.invoke(object);
            //return method.invoke(object, paramTypes);
        } catch (Exception e) {
            Log.e(TAG, "invokeMethod->methodName:" + methodName);
            Log.e(TAG, "invokeMethod->exception:" + e);

        }
        return null;
    } 



./packages/apps/Settings/src/com/android/settings/display/DrmDisplaySetting.java

 public static String[] getConnectorInfo() {
        Object rkDisplayOutputManager = null;
        try {
            rkDisplayOutputManager = Class.forName("android.os.RkDisplayOutputManager").newInstance();
        } catch (Exception e) {
            // no handle
        }
        if (rkDisplayOutputManager != null) {
            return (String[]) ReflectUtils.invokeMethodNoParameter(rkDisplayOutputManager, "getConnectorInfo");
        }
        return null;
    }

反射的基本概念
SettingLib
无法直接使用系统隐藏类、变量、接口导致的编译错误的 解决经验
android FrameWork 定制 绕开系统权限管控
开发解决Accessing hidden method限制

posted @   僵小七  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示