2012-03-23 27 views
9

Có một api không công khai mà tôi cần ghi đè để giải quyết sự lừa đảo với WebView của Android.Tôi có thể ghi đè lên một phương thức ẩn (nhưng công khai) và gọi phương thức siêu của nó không?

Các api ẩn nhưng nó là công cộng:

/** 
* ... 
* 
* @hide pending API council approval 
*/ 
public boolean selectText() { 
    ... 
} 

Vì vậy, tôi có thể ghi đè lên nó bằng cách đơn giản tuyên bố nó trong lớp WebView của riêng tôi, trừ đi @ Override:

public boolean selectText() { 
    ... 
} 

Có thể để gọi phương thức siêu từ ghi đè của tôi? Thông thường tôi có thể viết:

public boolean selectText() { 
    return super.selectText(); 
} 

Nhưng phương pháp này bị ẩn, do đó, super.selectText() không khả dụng. Nếu tôi sử dụng phản ánh:

public boolean selectText() { 
    return (Boolean) WebView.class.getMethod("selectText").invoke(this, (Object[]) null); 
} 

Tôi nhận được vòng lặp vô hạn vì nó gọi phương thức ghi đè của tôi.

Có cách nào để ghi đè phương thức này VÀ có thể gọi phương thức siêu không?

Cảm ơn!

+0

Không. AFAIK nó là không thể. – kosa

+1

Xem http://stackoverflow.com/questions/5411434/how-to-call-a-superclass-method-using-java-reflection và http://stackoverflow.com/questions/2100412/java-reflection-accessing- method-with-default-modifier-in-the-super-class và http://stackoverflow.com/questions/9771933/invoking-super-class-method-without-its-instance-using-reflection cho một số ý tưởng – CommonsWare

+0

nó hoàn toàn cần thiết để ghi đè lên phương pháp? Tại sao không gọi phương thức 'doSelectText()' của bạn, và sau đó sử dụng sự phản chiếu để gọi 'selectText()'? –

Trả lời

3

Có cách nào để ghi đè phương pháp này VÀ có thể gọi phương thức siêu không?

Không, thật không may, như được giải thích trong câu trả lời cho câu hỏi How to call a superclass method using Java reflection bạn không thể giải quyết vấn đề này với sự phản ánh.

+0

tôi không đồng ý - xem câu trả lời của tôi – ceph3us

1

Thực tế có một vài cách để thực hiện việc này, nhưng chúng tốn ít công sức, vì vậy có lẽ nên được sử dụng như một phương sách cuối cùng. Với một thiết bị bắt nguồn từ, bạn có thể trích xuất các biểu tượng từ các khung khuôn trên thiết bị và đặt chúng vào android.jar trong thư mục sdk/platforms/của bạn. Được sử dụng để có một kịch bản để làm điều này; mất nó trong việc chuyển đổi công việc.

bước từ bộ nhớ (lưu ý có thể bạn sẽ gặp khó khăn như tôi không nhớ các bước ... cho người dùng nâng cao hiểu những gì tôi đang cố gắng để có được ít):

  • adb pull/system/framework/* (đây là tất cả các tệp jar). Nó có thể là đủ để có được framework.jar. giải nén chúng.
  • cho mỗi người tôi tin rằng sẽ cung cấp cho bạn một classes.dex và một tệp kê khai. Nếu bạn chỉ nhận được file lớp, bỏ qua bước tiếp theo
  • dex2jar các classes.dex và unjar các classes_dex2jar.jar hoặc bất cứ đầu ra là từ dex2jar, mà sẽ cung cấp cho bạn một loạt các file .class
  • lấy các tệp lớp học và thêm chúng vào tệp android.jar android của bạn android.jar (sdk/platforms/android- # sdk #/android.jar).

Tôi đề nghị sao chép thư mục android- # sdk # vào thư mục android-1 # sdk #, vì vậy android-19 trở thành android-119 và sau đó thay đổi build.prop trong thư mục để nói ro.build. version.sdk = 119, và sau đó xây dựng dựa trên sdk 119. Bằng cách này bạn có thể chọn xây dựng chống lại 119 hoặc 119 bị tấn công của bạn. Chỉ cần không tham khảo bất kỳ tệp com.android.internal.R nào vì các id đó không chính xác trong kinh nghiệm của tôi.

Bây giờ bạn sẽ có thể biên dịch lại các biểu tượng này và truy cập chúng tốt. Mặc dù không phát điên nếu chúng thay đổi cách hoạt động của mọi thứ và chúng không có nghĩa vụ duy trì khả năng tương thích với các ứng dụng của bên thứ ba.

Điều này hoạt động vì thẻ ẩn chỉ được sử dụng trong bước biên dịch SDK và loại bỏ các biểu tượng này khỏi android.jar nằm trong sdk của bạn. Nếu chúng tôi thu thập tất cả các biểu tượng được biên dịch trên thiết bị và dính chúng vào bình sdk của bạn, nó giống như chúng chưa bao giờ bị tước bỏ. Hoặc bạn có thể kéo xuống và xây dựng cây android đầy đủ (https://source.android.com/source/building.html) và sau đó xây dựng ứng dụng của bạn dựa vào nguồn đầy đủ, bước đầu tiên về cơ bản là thu thập các ký hiệu đã biên dịch và làm việc với chúng.

0
  1. CÓ THỂ Bạn :) - phần đầu tiên của câu hỏi
  2. NO Bạn KHÔNG THỂ - thứ hai

giải pháp 1) - tốt nhất những gì bạn có thể làm ở đây gần nhất với những gì bạn muốn đạt được

// to override method 
// which IDE doesn't see - those that contains {@ hide} text in JavaDoc 
// simple create method with same signature 
// but remove annotation 
// as we don't know if method will be present or not in super class 
// 
//@Override  
public boolean callMethod(String arg) { 

    // can we do it ? 
    // boolean result = super.callMethod(arg) 
    // no why ? 
    // You may think you could perhaps 
    // use reflection and call specific superclass method 
    // on a subclass instance. 


/** 
* If the underlying method is an instance method, it is 
* invoked using dynamic method lookup as documented in The 
* Java Language Specification, Second Edition, section 
* 15.12.4.4; in particular, overriding based on the runtime 
* type of the target object will occur. 
*/ 


    // but always you can see what super class is doing in its method 
    // and do the same by forward call in this method to newly created one 
    // return modified result 
    return doSomthingWhatSuperDo() 
} 

solutions 2)

đối tượng (gọi phương thức này) thuộc về bạn? và triển khai giao diện?

nếu có thì sao về proxy?

  1. mở rộng lớp
  2. tạo Proxy
  3. sử dụng Proxy
  4. chặn gọi phương thức
  5. dựa trên một số điều kiện? gọi thực hiện của riêng hoặc quay trở lại ban đầu?
Các vấn đề liên quan