【发布时间】:2017-04-19 14:34:24
【问题描述】:
我做什么:
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);
}
实施:
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;
}
}
在那之后我的第一个错误消失了,现在我遇到了这个错误:
java.io.FileNotFoundException: /document/image:52214: open failed: ENOENT (No such file or directory)
怎么办?
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: 致命异常: main
进程:info.masterskaya.om.near,PID:8348
java.lang.IllegalStateException:在 Scheduler.Worker 线程上抛出异常。添加onError处理。
在 rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60)
在 android.os.Handler.handleCallback(Handler.java:733)
在 android.os.Handler.dispatchMessage(Handler.java:95)
在 android.os.Looper.loop(Looper.java:136)
在 android.app.ActivityThread.main(ActivityThread.java:5017)
在 java.lang.reflect.Method.invokeNative(Native Method)
在 java.lang.reflect.Method.invoke(Method.java:515)
在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
在 dalvik.system.NativeStart.main(本机方法)
原因:rx.exceptions.OnErrorNotImplementedException:无法为 rx.Observable 创建调用适配器
对于方法 ApiInterface.postImage
在 rx.Observable$26.onError(Observable.java:8524)
在 rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157)
在 rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120)
在 rx.internal.operators.OperatorDoOnEach$1.onError(OperatorDoOnEach.java:71)
在 rx.exceptions.Exceptions.throwOrReport(Exceptions.java:189)
在 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:无法为 rx.Observable 创建调用适配器
对于方法 ApiInterface.postImage
在 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)
在 retrofit2.Retrofit$1.invoke(Retrofit.java:145)
在 $Proxy0.postImage(本机方法)
在 info.masterskaya.om.near.mvp.model.ModelImpl.postImage(ModelImpl.java:53)
在 info.masterskaya.om.near.mvp.presenter.PresenterImpl$1.call(PresenterImpl.java:133)
在 info.masterskaya.om.near.mvp.presenter.PresenterImpl$1.call(PresenterImpl.java:119)
在 rx.Observable$11.onNext(Observable.java:4820)
在 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)
在 retrofit2.Retrofit.nextCallAdapter(Retrofit.java:217)
在 retrofit2.Retrofit.callAdapter(Retrofit.java:201)
在 retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:231)
... 20 更多
引起:rx.exceptions.OnErrorThrowable$OnNextValue: OnError 同时发出 onNext 值:android.net.Uri$HierarchicalUri.class
在 rx.exceptions.Exceptions.throwOrReport(Exceptions.java:189)
在 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: 致命异常: main
进程:info.masterskaya.om.near,PID:8618
java.lang.IllegalStateException:在 Scheduler.Worker 线程上抛出异常。添加onError处理。
在 rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:60)
在 android.os.Handler.handleCallback(Handler.java:733)
在 android.os.Handler.dispatchMessage(Handler.java:95)
在 android.os.Looper.loop(Looper.java:136)
在 android.app.ActivityThread.main(ActivityThread.java:5017)
在 java.lang.reflect.Method.invokeNative(Native Method)
在 java.lang.reflect.Method.invoke(Method.java:515)
在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
在 dalvik.system.NativeStart.main(本机方法)
引起:rx.exceptions.OnErrorNotImplementedException: /document/image:34: open failed: ENOENT (No such file or directory)
在 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)
在 rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:207)
在 rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
在 android.os.Handler.handleCallback(Handler.java:733)
在 android.os.Handler.dispatchMessage(Handler.java:95)
在 android.os.Looper.loop(Looper.java:136)
在 android.app.ActivityThread.main(ActivityThread.java:5017)
在 java.lang.reflect.Method.invokeNative(Native Method)
在 java.lang.reflect.Method.invoke(Method.java:515)
在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
在 dalvik.system.NativeStart.main(本机方法)
引起:java.io.FileNotFoundException:/document/image:34:打开失败:ENOENT(没有这样的文件或目录)
在 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)
在 okhttp3.MultipartBody.writeTo(MultipartBody.java:113)
在 okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:186)
在 okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:187)
在 okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
在 okhttp3.RealCall.execute(RealCall.java:57)
在改造 2.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)
在 rx.Subscriber.setProducer(Subscriber.java:205)
在 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)
在 rx.Observable.unsafeSubscribe(Observable.java:8741)
在 rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
在 rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
在 java.util.concurrent.FutureTask.run(FutureTask.java:237)
在 java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
在 java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
在 java.lang.Thread.run(Thread.java:841)
原因:libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
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; 名称="上传";文件名="IMG_20161206_092257.jpg" 12-09 05:37:55.760 10230-10372/ D/OkHttp:内容类型:multipart/form-data 12-09 05:37:55.760 10230-10372/* D/OkHttp:内容长度: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;名称=“名称” 12-09 05:37:55.770 10230-10372/ D/OkHttp: 内容传输编码:二进制 12-09 05:37:55.770 10230-10372/ D/OkHttp:内容类型:multipart/form-data;字符集=utf-8 12-09 05:37:55.770 10230-10372/ D/OkHttp:内容长度: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 正文)12-09 05:37:55.800 10230-10334/ D/GoogleCertificatesImpl: 获取 363 个 Google 证书 12-09 05:37:56.340 10230-10230/ I/Choreographer:跳过了 42 帧!该应用程序可能也在做 在它的主线程上做了很多工作。 12-09 05:37:56.390 10230-10372/ D/OkHttp: http://www./upload/index.php (604ms) 12-09 05:37:56.390 10230-10372/ D/OkHttp:日期:2016 年 12 月 9 日星期五 10:37:56 GMT 12-09 05:37:56.390 10230-10372/ D/OkHttp:服务器:Apache 12-09 05:37:56.390 10230-10372/ D/OkHttp:变化:接受编码 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 来自 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:连接:保持活动状态 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": “失败”} 12-09 05:37:56.390 10230-10372/*** D/OkHttp:
服务器:
<?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 都成功
【问题讨论】:
-
你解决了这个错误?
-
感谢您对我的问题的支持和关注,我曾经调试过:StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);
-
您可以将调度程序用于 NetworkOnMainThreadException 的一个错误选择
-
我尝试使用改造教程中的示例,其中使用了 File file = FileUtils.getFile(this, fileUri);但是没有成功,现在我尝试了两个步骤:-从图库中获取正确的文件-通过改造上传,但我认为主要问题出在这个错误中:无法为方法创建 rx.Observable
的调用适配器ApiInterface.postImage -
StrictMode 只有不好,其他只有好