2016-12-05 49 views
1

我該怎麼辦:RxJava:無法爲rx.Observable錯誤創建呼叫轉接

public interface ApiInterface { 
    @Multipart 
     @POST("/android/upload/index.php") 
     Observable<Response> postImage(@Part MultipartBody.Part image, @Part("name") RequestBody name); 
} 

型號:

public interface Model { 
Observable<Response> postImage(MultipartBody.Part image, RequestBody name); 
} 

默認地將Impl:

public class ModelImpl implements Model { 
    ApiModule apiModule = ApiModule.getInstance(); 
@Override 
    public Observable<Response> postImage(MultipartBody.Part image, RequestBody name) { 
     return apiModule.getApi().postImage(image,name); 
    } 
} 

主持人:

RxPhoto.requestUri(context, TypeRequest.GALLERY) 
     .flatMap(new Func1<Uri, Observable<Response>>() { 
      @Override 
      public Observable<Response> call(Uri uri) { 

       File file = new File(uri.getPath()); 
       RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); 
       MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile); 
       RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test"); 
       return model.postImage(body, name); 


      } 
     }).subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(new Subscriber<Response>() { 

        @Override 
        public void onError(Throwable e) { 

         Log.d(tag, "error:" + e); 

        } 

       }); 

我有錯誤:

錯誤:java.lang.IllegalArgumentException異常:無法創建呼叫轉接器rx.Observable 的方法ApiInterface.postImage

UPD:

我改變接口和其他人:

Observable<uploadAnswer> 


    public class uploadAnswer { 

     @SerializedName("success") 
     @Expose 
     private String success; 

     public String getSuccess() { 
      return this.success; 
     } 

    } 

之後,我的第一個呃ROR走了,現在我有這個錯誤:

java.io.FileNotFoundException:/文檔/圖片:52214:打開失敗:ENOENT(沒有這樣的文件或目錄)

怎麼辦?

UPD2:

我用這個函數來獲取文件URI:

public String getRealPathFromURIPath(Uri contentURI) { 
     Cursor cursor = context.getApplicationContext().getContentResolver().query(contentURI, null, null, null, null); 
     if (cursor == null) { 
      return contentURI.getPath(); 
     } else { 
      cursor.moveToFirst(); 
      int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); 
      return cursor.getString(idx); 
     } 
    } 

之後,我有這個錯誤(是意思,我是正確的?):

錯誤:android.os.NetworkOnMainThreadException

UPD3:

我的短代碼:

RxPhoto.requestUri(context,TypeRequest.GALLERY) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .doOnNext(new Action1<Uri>(){ 

        @Override 
        public void call(Uri uri) { 

         Log.d(tag, "up => " + uri); 

         File file = new File(uri.getPath()); 
         RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); 
         MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile); 
         RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test"); 

         //model.postImage(body, name); 

         GetDataSubscription = model.postImage(body,name) 
           .subscribeOn(Schedulers.io()) 
           .observeOn(AndroidSchedulers.mainThread()) 
           .subscribe(); 

        } 

       }) 
       .subscribe(); 

我仍然有錯誤:

E/AndroidRuntime:致命異常:主要 過程:info.masterskaya.om.near,PID: 8348 java.lang.IllegalStateException:在Scheduler.Worker線程上拋出的異常。添加onError處理。 at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method。invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android .internal.os.ZygoteInit.main(ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method) 原因:rx.exceptions.OnErrorNotImplementedException:無法爲方法創建rx.Observable 的調用適配器ApiInterface.postImage at rx.Observable $ 26.onError(Observable.java:8524) at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157) at rx.observ ers.SafeSubscriber.onError(SafeSubscriber.java:120) at rx.internal.operators.OperatorDoOnEach $ 1.onError(OperatorDoOnEach.java:71) at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:189) at rx .internal.operators.OperatorDoOnEach $ 1.onNext(OperatorDoOnEach.java:82) 在rx.internal.operators.OperatorObserveOn $ ObserveOnSubscriber.call(OperatorObserveOn.java:215) 在rx.internal.schedulers.ScheduledAction.run(ScheduledAction。 java:55) ... 9更多 導致:java.lang.IllegalArgumentException:無法爲方法ApiInterface.postImage爲rx.Observable 創建調用適配器在retrofit2.ServiceMethod $ Builder.methodError(ServiceMethod.java:695) 在retrofit2.ServiceMethod $ Builder.createCallAdapter(ServiceMethod.java:233) 在retrofit2.ServiceMethod $ Builder.build(ServiceMethod.java:159) 在retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166) at retrofit2.Refofit $ 1.invoke(Retrofit.java:145) at $ Proxy0.postImage(Native Method) at info.masterskaya.om.near.mvp.model (ModelImpl.java:53) at info.masterskaya.om.near.mvp.presenter.PresenterImpl $ 1.call(PresenterImpl.java:133) at info.masterskaya.om.near.mvp.pr esenter.PresenterImpl $ 1.call(PresenterImpl.java:119) at rx.Observable $ 11.onNext(Observable.java:4820) at rx.internal.operators.OperatorDoOnEach $ 1.onNext(OperatorDoOnEach.java:80) .. 11更 引起:java.lang.IllegalStateException:響應必須被參數化爲在retrofit2.adapter.rxjava.RxJavaCallAdapterFactory.getCallAdapter(RxJavaCallAdapterFactory.java:119)響應或響應 在retrofit2.adapter.rxjava.RxJavaCallAdapterFactory.get (RxJavaCallAdapterFactory.java:105) at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:217) at retrofit2.Retrofit.callAdapter(Retrofit.java:20 1) at retrofit2.ServiceMethod $ Builder.createCallAdapter(ServiceMethod.java:231) ... 20個以上 由rx.exceptions.OnErrorThrowable引起$ OnNextValue:發出onNext值時的OnError:android.net.Uri $ HierarchicalUri。類 at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:189) at rx.internal.operators.OperatorDoOnEach $ 1.onNext(OperatorDoOnEach.java:82) ...11多

如果我改變我的接口:

@Multipart 
    @POST("/upload/index.php") 
    Observable<String> postImage(@Part MultipartBody.Part image, @Part("name") RequestBody name); 

我有這樣的痕跡:

* E/AndroidRuntime:致命異常:主要 過程:info.masterskaya.om.near, PID:8618 java.lang.IllegalStateException:在Scheduler.Worker線程上拋出的異常。添加onError處理。 at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java .lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:595) at dalvik.system.NativeStart.main(Native Method) 由rx.exceptions.OnErrorNotImplementedException引起:/ document/image:34:打開失敗:ENOENT(無此類文件或目錄) at rx.Observable $ 26.onError( Observable.java:8524) 在rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157) 在rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) 在rx.internal.operators.OperatorObserveOn $ ObserveOnSubscriber。 checkTerminated(OperatorObserveOn.java:264) at rx.internal.operators.OperatorObserveOn $ ObserveOnSubscriber.call(OperatorObserveOn.java:207) at rx.internal.schedulers.ScheduledAct ion.run(ScheduledAction.java:55) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper。在java.lang.reflect.Method.invoke處使用循環(Looper.java:136) (Method.java:515) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:779) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 在dalvik.system.Native Start.main(本地方法) 引起:java.io.FileNotFoundException:/ document/image:34:打開失敗:ENOENT(沒有這樣的文件或目錄) at libcore.io.IoBridge.open(IoBridge.java:409 ) 在java.io.FileInputStream中。(FileInputStream.java:78) 在okio.Okio.source(Okio.java:163) 在okhttp3.RequestBody $ 3.writeTo(RequestBody.java:117) 在okhttp3.MultipartBody .writeOrCountBytes(MultipartBody.java:171) at okhttp3.MultipartBody.writeTo(MultipartBody.java:113) at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:186) at ok http3.RealCall $ ApplicationInterceptorChain.proceed(RealCall.java:187) at okhttp3.RealCall。getResponseWithInterceptorChain(RealCall.java:160) 在okhttp3.RealCall.execute(RealCall.java:57) 在retrofit2.OkHttpCall.execute(OkHttpCall.java:174) 在retrofit2.adapter.rxjava.RxJavaCallAdapterFactory $ RequestArbiter.request( RxJavaCallAdapterFactory.java:171) 在rx.internal.operators.OperatorSubscribeOn $ 1 $ 1 $ 1.request(OperatorSubscribeOn.java:80) 在rx.Subscriber.setProducer(Subscriber.java:211) 在rx.internal.operators.OperatorSubscribeOn $ 1 $ 1.setProducer(OperatorSubscribeOn.java:76) at rx.Subscriber.setProducer(Subscriber.java:205) at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory $ CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152) 在retrofit2.adapter.rxjava.RxJavaCallAdapterFactory $ CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138) 在rx.Observable $ 2.call(Observable.java:233) 在rx.Observable $ 2.call(Observable.java:225) at rx.Observable.unsafeSubscribe(Observable.java:8741) at rx.internal.operators.OperatorSubscribeOn $ 1.call(OperatorSubscribeOn.java:94) at rx.internal.schedulers .ScheduledAction.run(ScheduledAction.java:55) at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:422) at java.util.concurrent.FutureTask.run(FutureTask.java: 237) 處的java.util.concurrent java.util.concurrent.ScheduledThreadPoolExecutor中$ $ ScheduledFutureTask.access 201(ScheduledThreadPoolExecutor.java:152) 在java.util.concurrent.ScheduledThreadPoolExecutor中$ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) .ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) 由:libcore.io.ErrnoException:打開失敗:ENOENT(無此文件或目錄)

                 at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 
                     at libcore.io.IoBridge.open(IoBridge.java:393) 
                     at java.io.FileInputStream.<init>(FileInputStream.java:78)  
                     at okio.Okio.source(Okio.java:163)  
                     at okhttp3.RequestBody$3.writeTo(RequestBody.java:117)  
                     at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:171)  
                     at okhttp3.MultipartBody.writeTo(MultipartBody.java:113)  
                     at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:186)  
                     at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:187)  
                     at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)  
                     at okhttp3.RealCall.execute(RealCall.java:57)  
                     at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)  
                     at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$RequestArbiter.request(RxJavaCallAdapterFactory.java:171)  
                     at rx.internal.operators.OperatorSubscribeOn$1$1$1.request(OperatorSubscribeOn.java:80)  
                     at rx.Subscriber.setProducer(Subscriber.java:211)  
                     at rx.internal.operators.OperatorSubscribeOn$1$1.setProducer(OperatorSubscribeOn.java:76)  
                     at rx.Subscriber.setProducer(Subscriber.java:205)  
                     at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:152)  
                     at retrofit2.adapter.rxjava.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:138)  
                     at rx.Observable$2.call(Observable.java:233)  
                     at rx.Observable$2.call(Observable.java:225)  
                     at rx.Observable.unsafeSubscribe(Observable.java:8741)  
                     at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)  
                     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)  
                     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)  
                     at java.util.concurrent.FutureTask.run(FutureTask.java:237)  
                     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)  
                     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)  
                     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)  
                     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)  
                     at java.lang.Thread.run(Thread.java:841)*  

UPD4:

我有一些結果。

接口:

@Multipart 
@POST("/upload/index.php") 
Observable<Void> postImage(@Part MultipartBody.Part image, @Part("name") RequestBody name); 

主要功能:

RxPhoto.requestUri(context,TypeRequest.GALLERY) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .doOnNext(new Action1<Uri>(){ 

        @Override 
        public void call(Uri uri) { 

         Log.d(tag, "up => " + uri); 
         Log.d(tag, "getPath => " + getPath(context,uri)); 

         String URL = getPath(context,uri); 

         File file = new File(URL+""); 

         RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file); 
         MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile); 
         RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload_test"); 

         GetDataSubscription = model.postImage(body,name) 
           .subscribeOn(Schedulers.io()) 
           .observeOn(AndroidSchedulers.mainThread()) 
           .subscribe(); 

        } 

       }) 
       .subscribe(); 

/~~~~~~~/

getPath(context,uri) 

我發現HERE

現在我有服務器錯誤:

12-09 05:37:55.760 10230-10372/* D/OkHttp: --857d62de-296c-4d23-8683-92b3b340a658 12-09 05:37:55.760 10230-10372/ D/OkHttp: Content-Disposition: form-data; name="upload"; filename="IMG_20161206_092257.jpg" 12-09 05:37:55.760 10230-10372/ D/OkHttp: Content-Type: multipart/form-data 12-09 05:37:55.760 10230-10372/* D/OkHttp: Content-Length: 26188

...

12-09 05:37:55.770 10230-10372/* D/OkHttp: --857d62de-296c-4d23-8683-92b3b340a658 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Disposition: form-data; name="name" 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Transfer-Encoding: binary 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Type: multipart/form-data; charset=utf-8 12-09 05:37:55.770 10230-10372/ D/OkHttp: Content-Length: 11 12-09 05:37:55.770 10230-10372/ D/OkHttp: upload_test 12-09 05:37:55.770 10230-10372/ D/OkHttp: --857d62de-296c-4d23-8683-92b3b340a658-- 12-09 05:37:55.770 10230-10372/ D/OkHttp: --> END POST (26620-byte body) 12-09 05:37:55.800 10230-10334/ D/GoogleCertificatesImpl: Fetched 363 Google certificates 12-09 05:37:56.340 10230-10230/ I/Choreographer: Skipped 42 frames! The application may be doing too much work on its main thread. 12-09 05:37:56.390 10230-10372/ D/OkHttp: <-- 200 OK http://www ./upload/index.php (604ms) 12-09 05:37:56.390 10230-10372/ D/OkHttp: Date: Fri, 09 Dec 2016 10:37:56 GMT 12-09 05:37:56.390 10230-10372/ D/OkHttp: Server: Apache 12-09 05:37:56.390 10230-10372/ D/OkHttp: Vary: Accept-Encoding 12-09 05:37:56.390 10230-10372/ D/OkHttp: Content-Type: text/html; charset=UTF-8 12-09 05:37:56.390 10230-10372/ D/OkHttp: X-Cache: MISS from t7..ru 12-09 05:37:56.390 10230-10372/ D/OkHttp: X-Cache-Lookup: MISS from t7..ru:6666 12-09 05:37:56.390 10230-10372/ D/OkHttp: Connection: keep-alive 12-09 05:37:56.390 10230-10372/ D/OkHttp: OkHttp-Sent-Millis: 1481279876016 12-09 05:37:56.390 10230-10372/ D/OkHttp: OkHttp-Received-Millis: 1481279876396 12-09 05:37:56.390 10230-10372/* D/OkHttp: {"result": "fail"} 12-09 05:37:56.390 10230-10372/*** D/OkHttp: <-- END HTTP (18-byte body)

服務器:

<?php 

    $file_path = "up/"; 

    $file_path = $file_path . basename($_FILES['uploaded_file']['name']); 
    if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)){ 
     echo '{"result": "success"}'; 
    } else{ 
     echo '{"result": "fail"}'; 
    } 
?> 

UPD5:

我做到了這一點他媽的上傳!

PHP測試代碼:

<?php 

    error_reporting(E_ALL); 
    ini_set('display_errors', 1); 

    define('ROOT_DIR', dirname(__FILE__)); 

    $file_path = ROOT_DIR . ""; 

    $file_path = $file_path . basename($_FILES['upload']['name']); 
    if(move_uploaded_file($_FILES['upload']['tmp_name'], $file_path)){ 
     echo '{"result": "success"}'; 
    } else{ 
     echo '{"result": "fail"}'; 
    } 
?> 

所有我遇到的問題是對設備正確URI。嘗試API 16,19和24全部成功

+0

你解決了這個錯誤的響應? –

+0

感謝您對我的問題的支持和興趣,我曾經調試過 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()。permitAll()。build(); StrictMode.setThreadPolicy(policy); –

+0

那一個不好的選項,你可以使用調度程序的NetworkOnMainThreadException –

回答

1

包含呼叫適配器工廠,如果您忘記了它。

RxJava2:compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

RxJava:compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'

編輯:

好,是因爲你需要轉換multipart,不text,這樣的變化將出現在這裏:

RequestBody name = RequestBody.create(MediaType.parse("multipart/form-data"), "upload_test"); 

mediatype也應該是山姆e

RequestBody reqFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);` 

欲瞭解更多信息,請看看here

+0

不,同樣的錯誤:( –

+0

在這個錯誤我想是因爲你已經添加了兩行相同的庫。我認爲你的問題是這樣的 –

+0

請閱讀我的更新 –

1

如果name參數只是字符串,我認爲API應該這樣調用:

public interface ApiInterface { 
    @Multipart 
     @POST("/android/upload/index.php") 
     Observable<Response> postImage(@Part MultipartBody.Part image, @Part("name") String name); 
} 
+0

請閱讀我的更新 –

1

的問題是在以下部分:

Observable<Response> 

響應總是需要指定體型。它看起來像你的迴應沒有一個身體,所以你應該與此替換它:

Observable<Result<Void>> 

...,並要求使用result.response()