【问题标题】:Android Reflection confusionAndroid反射混淆
【发布时间】:2012-10-17 11:34:21
【问题描述】:

我正在尝试反映一个 Android 类,我们知道它可以完成,因为其他应用程序正在这样做,但我们自己却难以实现结果。

我们被困在下面

Class<?> myClass = Class.forName("android.content.pm.PackageManager");
Method method = myClass.getMethod("deleteApplicationCacheFiles", String.class,IPackageDataObserver.class);

IPackageDataObserver.class 不存在

import android.content.pm.IPackageDataObserver;

也不起作用,我可以手动从 Google 获取接口的代码并将它们放入 Package 中,但这似乎有点 OTT,想知道我是否遗漏了什么。

谢谢

【问题讨论】:

    标签: android reflection


    【解决方案1】:

    编辑:

    将 IPackageDataObserver 类添加到您自己的项目中,这是唯一的方法。

    在你的源文件夹中创建一个包,命名为“android.content.pm”并添加这个类,这个类只是原始的android源代码:

    /*
     * This file is auto-generated.  DO NOT MODIFY.
     * Original file: frameworks/base/core/java/android/content/pm/IPackageDataObserver.aidl
     */
    package android.content.pm;
    /**
     * API for package data change related callbacks from the Package Manager.
     * Some usage scenarios include deletion of cache directory, generate
     * statistics related to code, data, cache usage(TODO)
     * {@hide}
     */
    public interface IPackageDataObserver extends android.os.IInterface
    {
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageDataObserver
    {
    private static final java.lang.String DESCRIPTOR = "android.content.pm.IPackageDataObserver";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
    this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an android.content.pm.IPackageDataObserver interface,
     * generating a proxy if needed.
     */
    public static android.content.pm.IPackageDataObserver 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 android.content.pm.IPackageDataObserver))) {
    return ((android.content.pm.IPackageDataObserver)iin);
    }
    return new android.content.pm.IPackageDataObserver.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_onRemoveCompleted:
    {
    data.enforceInterface(DESCRIPTOR);
    java.lang.String _arg0;
    _arg0 = data.readString();
    boolean _arg1;
    _arg1 = (0!=data.readInt());
    this.onRemoveCompleted(_arg0, _arg1);
    return true;
    }
    }
    return super.onTransact(code, data, reply, flags);
    }
    private static class Proxy implements android.content.pm.IPackageDataObserver
    {
    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;
    }
    public void onRemoveCompleted(java.lang.String packageName, boolean succeeded) throws android.os.RemoteException
    {
    android.os.Parcel _data = android.os.Parcel.obtain();
    try {
    _data.writeInterfaceToken(DESCRIPTOR);
    _data.writeString(packageName);
    _data.writeInt(((succeeded)?(1):(0)));
    mRemote.transact(Stub.TRANSACTION_onRemoveCompleted, _data, null, android.os.IBinder.FLAG_ONEWAY);
    }
    finally {
    _data.recycle();
    }
    }
    }
    static final int TRANSACTION_onRemoveCompleted = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    }
    public void onRemoveCompleted(java.lang.String packageName, boolean succeeded) throws android.os.RemoteException;
    }
    

    罗尔夫

    【讨论】:

      【解决方案2】:

      这个问题有 1 年,但我喜欢用一些有用的信息来完成它,其他解决方案是添加到您的项目中的 lib layoutlib.jar,它位于 plaform//data 中并按提供的方式编译(这不包括在您的二进制文件中),通过这种方式,您的项目可以解决依赖关系,因为这个类不在公共 sdk 上。

      【讨论】:

      • 如何添加 layoutlib.jar 文件??
      • 你可以在 plaform/android-/data/ 上找到 layoutlib。如果您使用的是 gradle,请将 jar 放在您的 libs 文件夹中,并在 build.xml 中添加对提供的文件行的依赖项('libs/layoutlib.jar')
      • 我正在使用 Eclipse,我已经添加了 layoutlib.jar,但这段代码仍然在 onRemoveComplete 覆盖方法中返回我的包名 null
      【解决方案3】:

      我认为问题在于 IPackageDataObserver 是原始的 AIDL 文件,因此它在运行时在 gen 文件夹而不是 src 文件夹中生成。所以解决方案是将IPackageDataObserver.aidl 添加到您的项目中,并记住保持此文件是最新的。可以获取IPackageDataObserver的内容。

      /*
      **
      ** Copyright 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 android.content.pm;
      
      /**
       * API for package data change related callbacks from the Package Manager.
       * Some usage scenarios include deletion of cache directory, generate
       * statistics related to code, data, cache usage(TODO)
       * {@hide}
       */
      oneway interface IPackageDataObserver {
          void onRemoveCompleted(in String packageName, boolean succeeded);
      }
      

      另一个类似的 SO question

      【讨论】:

        猜你喜欢
        • 2011-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-31
        • 2011-03-22
        • 1970-01-01
        • 1970-01-01
        • 2011-04-07
        相关资源
        最近更新 更多