2012-05-11 3 views
0

Вот довольно запутанный вопрос. Я пытаюсь получить доступ к элементу экземпляра webviewcore веб-просмотра через отражение. Мне нужна ссылка на webviewcore, которая используется моим веб-просмотром, поэтому я могу вызвать метод, который использует webviewcore. Я должен сделать это через отражение, потому что публичный sdk не позволяет вам получить доступ к этому классу. Я знаю, что использование рефлексии для этого не рекомендуется, но я успокоился.Android: как получить экземпляр поля члена через отражение

Я прочитал here, что для достижения этой цели я хотел бы сделать что-то вроде этого:

Class aClass = MyObject.class 
Field field = aClass.getField("someField"); 

MyObject objectInstance = new MyObject(); 

Object value = field.get(objectInstance); 

field.set(objetInstance, value); 

Проблема с делать это (и, возможно, им-недоразумение это) является то, что она выглядит, как я должен создать новый экземпляр WebViewCore для работы с ним, а затем установите его обратно в мой экземпляр. Сначала и формост, я понимаю это правильно. Если да, то кто-то может перевести код выше, чтобы сделать то, что я ищу. Если мое понимание неверно, кто-нибудь знает, как еще я могу получить доступ к WebViewCore экземпляра веб-представления?

Спасибо!

EDIT: Из-за путаницы я переформулирую свой вопрос. У меня есть экземпляр webview. Этот веб-просмотр имеет поле-член, называемое «mWebViewCore», которое является экземпляром класса WebViewCore. WebViewCore имеет класс-член под названием TextSelectionData. Мне нужно получить доступ к объекту TextSelectionData с помощью отражения. Я знаю, как получить доступ к полям и методам веб-просмотра через отражение. Поэтому я могу получить поле mWebViewCore, но я не знаю, как взять это поле и получить доступ к его полям, методам, классам и т. Д. Широкие штрихи берут экземпляр объекта, определяют конкретное поле в этом экземпляре и получают доступ к полям этого поля.

Извините за путаницу. Это происходит из-за моего слабого понимания рефлексии и частично из-за того, что я недостаточно изучил класс WebViewCore. вот где я получил в коде:

Class c = mWebView.getClass(); 

     try { 
      Field webViewCoreField = c.getDeclaredField("mWebViewCore"); 
      webViewCoreField.setAccessible(true); 
      //how do i get the fields of webViewCoreField? 
     } 
+0

Аргумент 'Field.get' - это экземпляр, из которого вы пытаетесь получить указанное поле. Зачем вам создавать новый? Тогда вы не получите тот набор, который вам нужен. –

+0

Я вижу; вы следуете учебнику Jenkiv и неправильно понимаете его: этот учебник создает экземпляр класса для извлечения поля из-за отсутствия экземпляра - у вас уже есть * экземпляр. –

+0

У меня есть экземпляр webview, а не webviewcore. Я хочу получить доступ к одному из полей webviewcore. Поле webviewcore - это сам объект, поэтому я не могу просто установить значение, потому что значение этого поля является объектом, который я не могу создать. Простите, если это сбивает с толку. Может ли один из вас предоставить какой-то код о том, как это сделать. – aamiri

ответ

1

Предполагая WebViewCore с private String s поле:

public class WebViewCore { 
    private String s; 
    public WebViewCore(String s) { this.s = s; } 
    @Override 
    public String toString() { 
     return "WebViewCore{" + "s='" + s + '\'' + '}'; 
    } 
} 

Предполагая WebView с private WebViewCore webViewCore поле:

public class WebView { 
    private WebViewCore webViewCore; 
    public WebView() { webViewCore = new WebViewCore("ohai"); } 
} 

Теперь мы задумываемся:

общественного класса Main {

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { 
     // First get the private WebViewCore field... 
     Field fWvc = WebView.class.getDeclaredField("webViewCore"); 
     fWvc.setAccessible(true); 
     System.out.println(fWvc); 

     // Then get an instance of a WebView; you already have one, 
     // I'm constructing one... 
     WebView wv = new WebView(); 
     WebViewCore wvc = (WebViewCore) fWvc.get(wv); 
     System.out.println(wvc); 

     // Now get the private String field from the WebViewCore class... 
     Field fS = WebViewCore.class.getDeclaredField("s"); 
     fS.setAccessible(true); 
     System.out.println(fS); 

     // Now get the value of the private String field from the instance 
     // of the WebViewCore we retrieved above... 
     String s = (String) fS.get(wvc); 
     System.out.println(s); 
    } 

} 

Итак, вот моя тирада: отражение относительно передовой техники, хотя это довольно прямо вперед. (С предостережением я делал это очень долго, с языками, которые обладают лучшими отражающими способностями, чем Java.)

Это, похоже, все еще немного вне досягаемости - Я был бы действительно, действительно заботился об использовании его и избегал бы его практически любой ценой. Я сомневаюсь в том, что вам нужно делать то, что вы пытаетесь сделать, и после этого я задал вопрос о том, что вы пытаетесь сделать, до тех пор, пока такие вещи, как пример игрушек, мы не сбрасываем с здесь возникают нулевые концептуальные проблемы.

Здесь есть драконы, и они будут готовить и есть вас.

+0

Благодарим за помощь. – aamiri

1

Reflection предлагает Вам возможность доступа частных полей, частные методы класса (или, скорее, объект), а также информацию во время выполнения.

Ваше понимание рефлексии верно. Но в фрагменте кода, который вы опубликовали, ваше использование отражения не имеет для меня смысла. Вы устанавливаете значение в поле со значением из этой области, то есть вы делаете что-то вроде:

obj.setValue(obj.getValue()); 

Вы сказали, что вы хотите получить доступ личного поля WebView, я предполагаю, что у вас уже есть WebView экземпляр, поэтому, как только вы получите ссылку на поле, вы просто установите значение этого поля в своем оригинальном экземпляре WebView, вы не должны не и не должны создать новый объект WebView, потому что это был оригинальный объект WebView, который вы хотели для работы.

Что-то вроде этого:

WebView myWebView = ...; 
Object myValueToSet = ...; 
Class webViewClass = WebView.class 
Field field = webViewClass.getField("someField"); 
field.setAccessible(true); 
field.set(myWebView, myValueToSet); 
Смежные вопросы