2011-11-08 21 views
6

Tôi có câu hỏi về cách sử dụng GWT-RequestFactory trong Android. Như một điểm khởi đầu, tôi đã sử dụng mã từ “Tạo một AppEngine kết nối Android-Project” -Wizard (infos: http://code.google.com/intl/de-DE/eclipse/docs/appengine_connected_android.html) và nó đã làm việc tuyệt vời.Cách sử dụng GWT-RequestFactory trong Android SyncAdapter (luôn nhận được ValidationTool-Error)

Nhưng bây giờ trong trường hợp của tôi, tôi muốn mở rộng ứng dụng này để sử dụng một ContentProvider cục bộ với SQLite và SyncService với SyncAdapter làm đồng bộ hóa dữ liệu từ ContentProvider với AppEngine bằng cách sử dụng RequestFactory. Bây giờ vấn đề của tôi như sau: Tôi có thể gọi

MyRequestFactory requestFactory = Util.getRequestFactory(mContext, MyRequestFactory.class); 

trong bất kỳ Hoạt động tôi muốn và sẽ nhận được một thể hiện của MyRequestFactory. (Lưu ý: Util là một lớp được tạo bởi Wizard.) Nhưng nếu tôi cố gắng thực hiện cùng một cuộc gọi từ SyncAdapter của mình, tôi sẽ nhận được một java.lang.RuntimeException: RequestFactory ValidationTool phải được chạy cho com.hotool.client .MyRequestFactory RequestFactory type ".

Có lẽ đối với thông tin của bạn: Phương pháp Util.getRequestFacory trông như thế này:

/** 
* Creates and returns an initialized {@link RequestFactory} of the given 
* type. 
*/ 
public static <T extends RequestFactory> T getRequestFactory(
     Context context, Class<T> factoryClass) { 

    T requestFactory = RequestFactorySource.create(factoryClass); 

    SharedPreferences prefs = getSharedPreferences(context); 
    String authCookie = prefs.getString(Util.AUTH_COOKIE, null); 

    String uriString = Util.getBaseUrl(context) + RF_METHOD; 
    URI uri; 
    try { 
     uri = new URI(uriString); 
    } catch (URISyntaxException e) { 
     Log.w(TAG, "Bad URI: " + uriString, e); 
     return null; 
    } 
    requestFactory.initialize(new SimpleEventBus(), 
      new AndroidRequestTransport(uri, authCookie)); 

    return requestFactory; 
} 

Lỗi này xảy ra trong RequestFactorySource nằm trong requestfactory-client.jar Tôi nghĩ rằng, điều này có thể trở thành vấn đề của Trình tải lớp, nhưng đã cố gắng tìm ra vấn đề đó mà không thành công.

tôi cố gắng sử dụng ValidationTool nhưng trước hết nó không giúp đỡ và thứ hai tôi phát hiện ra, rằng các lớp học ValidationTool sẽ tạo ra đã được tại chỗ (có thể là nhờ vào chú thích chế biến như đã đề cập ở đây: http://code.google.com/p/google-web-toolkit/wiki/RequestFactoryInterfaceValidation)

Có ai có ý tưởng gì có thể gây ra điều này không?

Cảm ơn bạn rất nhiều và kính trọng.

Markus Neuenschwander

+0

Tôi chạy vào cùng một lỗi, tôi đã tìm thấy thứ gì đó trên http://how2code.wordpress.com/2011/12/02/error-the-requestfactory-validationtool-must-be-run-for-gwt- 2-4 /, nhưng điều đó không giải quyết được vấn đề cho tôi. – bembii

Trả lời

4

Bạn đúng Mark, đây là vấn đề về trình tải lớp.

Nó xảy ra trong requestfactory-client.jar, đây là nguồn gốc liên quan:

class InProcessRequestFactory extends AbstractRequestFactory { 

    //... 

    public InProcessRequestFactory(Class<? extends RequestFactory> requestFactoryInterface) { 
     this.requestFactoryInterface = requestFactoryInterface; 
     deobfuscator = 
      Deobfuscator.Builder.load(requestFactoryInterface, 
       Thread.currentThread().getContextClassLoader()).build(); 
    } 

    //... 

} 

public class Deobfuscator { 

    //... 

    public static class Builder { 
     public static Builder load(Class<?> clazz, ClassLoader resolveClassesWith) { 
      Throwable ex; 
      try { 
       Class<?> found; 
       try { 
        // Used by the server 
        found = Class.forName(clazz.getName() + GENERATED_SUFFIX, false, resolveClassesWith); 
       } catch (ClassNotFoundException ignored) { 
        // Used by JRE-only clients 
        found = Class.forName(clazz.getName() + GENERATED_SUFFIX_LITE, false, resolveClassesWith); 
       } 
       Class<? extends Builder> builderClass = found.asSubclass(Builder.class); 
       Builder builder = builderClass.newInstance(); 
       return builder; 
      } catch (ClassNotFoundException e) { 
       throw new RuntimeException("The RequestFactory ValidationTool must be run for the " 
        + clazz.getCanonicalName() + " RequestFactory type"); 
      } catch (InstantiationException e) { 
      ex = e; 
     } catch (IllegalAccessException e) { 
      ex = e; 
     } 
     throw new RuntimeException(ex); 
    } 

    //... 

} 

Vấn đề là Thread.currentThread() getContextClassLoader() dường như trở lại. giá trị null khi được gọi từ bộ điều hợp đồng bộ hóa trên Android, bởi vì chủ đề Bộ điều hợp đồng bộ được tạo bởi Hệ thống chứ không phải bởi ứng dụng của bạn.

tôi giải quyết này bằng cách gọi bằng tay gọi setContextClassLoader trong phương pháp onPerformSync trước khi tạo một trường hợp requestfactory:

@Override 
public void onPerformSync(final Account account, Bundle extras, 
     String authority, final ContentProviderClient provider, 
     final SyncResult syncResult) { 

    Thread.currentThread().setContextClassLoader(mContext.getClassLoader()); 

    // ... 

    MyRequestFactory requestFactory = Util.getRequestFactory(mContext, 
      MyRequestFactory.class, acsidToken); 

    // ... 
} 

Tôi hy vọng điều này có ý nghĩa. Andreas

+1

Cảm ơn bạn! Điều đó giải quyết được vấn đề. Có nó chạy ngay trước khi bạn trả lời câu hỏi ở đây. Dù sao cũng cảm ơn bạn. – Qsi

+0

Câu trả lời đáng gờm. Lưu dự án của tôi! –

+0

Tuyệt vời Andreas! Điều này cố định một vấn đề cực kỳ khó khăn. – aez