- GRPC获取服务器数据是耗时操作,不能写在UI主线程中,可以写在子线程或使用AsyncTask实现获取数据,但实测,仅仅是获取少量数据,可以写在UI主线程中(虽然不推荐这么做)。目前博主在AsyncTask中的doInBackground()实现获取服务器数据(数据量比较少),再在onPostExecute()中实现对UI的数据加载,会有很长时间的延迟,目前这个问题待解决//TODO。
下面给出博主的AsyncTask的代码
class myAsyncTask extends AsyncTask<Void,Void,List<UpdateNews>> {
@Override
protected List<UpdateNews> doInBackground(Void... voids) {
List<UpdateNews> updateNewsList = new ArrayList<UpdateNews>();
UpdateNews[] messageGot=new UpdateNews[limit];
ManagedChannel mChannel;
mChannel = ManagedChannelBuilder.forAddress(HOST, PORT)
.usePlaintext()
.build();
DataServiceGrpc.DataServiceBlockingStub stub = DataServiceGrpc.newBlockingStub(mChannel);
Dataservice.MsgRequest message = Dataservice.MsgRequest.newBuilder()
.setStart(start)
.setLimit(limit)
.setTitle(title_)
.setContent(content_)
.build();
Dataservice.MsgResponse response = stub.getNews(message);
for (int i = 0; i < limit; i++) {
messageGot[i].setTime(response.getRep(i).getPublishDate());
messageGot[i].setAbstrnews(response.getRep(i).getTitle());
updateNewsList.add(messageGot[i]);
}
try {
//关闭channal
mChannel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
return updateNewsList;
}
@Override
protected void onPostExecute(List<UpdateNews> list){
uNewsList=list;
}
}
AsyncTask<Params,Progress,Result>是一个抽象类,通常用于被继承.继承AsyncTask需要指定如下三个泛型参数:
Params:启动任务时输入的参数类型.
Progress:后台任务执行中返回进度值的类型.
Result:后台任务执行完成后返回结果的类型(doInBackground的返回值类型).
.构建AsyncTask子类的回调方法
AsyncTask主要有如下几个方法:
doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成.
onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作.
onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法.通过此方法进行UI的更新.
onProgressUpdate:当在doInBackground方法中调用publishProgress方法更新任务执行进度后,将调用此方法.通过此方法我们可以知晓任务的完成进度.
- 博主作为一个安卓小白,对于安卓的网络请求不是很熟悉,对于GRPC,遇到很多坑,目前自己也没法解决,先在这里挖坑,日后再填。
在请求一个自定义类型的数据时,遇到了网络请求错误,错误提示Caused by: io.grpc.StatusRuntimeException: INTERNAL: grpc: error while marshaling: proto: Marshal called with nil
,目前网上关于GRPC的资料比较少,具体解决方法目前没找到//TODO。
完整错误提示:
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.zyk97.infotest, PID: 27554
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: io.grpc.StatusRuntimeException: INTERNAL: grpc: error while marshaling: proto: Marshal called with nil
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:233)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:214)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:139)
at com.dib.pann.DataServiceGrpc$DataServiceBlockingStub.getNews(DataServiceGrpc.java:347)
at com.example.zyk97.infotest.Fragment.Fragment1$myAsyncTask.doInBackground(Fragment1.java:111)
at com.example.zyk97.infotest.Fragment.Fragment1$myAsyncTask.doInBackground(Fragment1.java:93)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)