感觉renren SDK的异步发送消息机制不是很好,其实不能这么说.为什么呢?看下文
先来介绍一下
它使用了一个异步类来处理请求数据,上传数据等的操作 ,这个类在sdk的AsyncRenren 以及他的辅助类StatusHelper等里面,这些异步类通过线程池的方式进行耗时操作 在demo中调用这个异步类发送数据,
那发送的数据怎么通知UI更新呢?于是使用了一个listener 在demo的Activity中定义一个listener继承自sdk中的listener 这样sdk中的类就可以调用出入的listener进而操作UI了
拿发送状态为例
在 StatusPublishActivity中,有
StatusSetRequestParam param = new StatusSetRequestParam(status .getText().toString().trim()); StatusSetListener listener = new StatusSetListener( StatusPublishActivity.this); try { AsyncRenren aRenren = new AsyncRenren(renren); aRenren.publishStatus(param, listener, // 对结果进行监听 true); // 若超过140字符,则自动截短 } catch (Throwable e) { String errorMsg = e.getMessage(); response.setText(errorMsg); }
我们看一下这个方法
public void publishStatus(StatusSetRequestParam status, AbstractRequestListener<StatusSetResponseBean> listener, boolean truncOption) { StatusHelper helper = new StatusHelper(renren); helper.asyncPublish(pool, status, listener, truncOption); }
/** * 异步发送状态的方法 * * @param pool * 执行发送状态操作的线程池 * @param status * 要发布的状态对象 * @param listener * 用以监听发布状态结果的监听器对象 * @param truncOption * 若超出了长度,是否自动截短至140个字 */ public void asyncPublish(Executor pool, final StatusSetRequestParam status, final AbstractRequestListener<StatusSetResponseBean> listener, final boolean truncOption) { pool.execute(new Runnable() { @Override public void run() { try { StatusSetResponseBean stat = publish(status); if(listener != null) { listener.onComplete(stat); } } catch (RenrenException rre) { // 参数、服务器等错误或异常 Util.logger(rre.getMessage()); if (listener != null) { listener.onRenrenError(new RenrenError(rre .getErrorCode(), rre.getMessage(), rre .getOrgResponse())); } } catch (Throwable t) { // 运行时异常 Util.logger(t.getMessage()); if (listener != null) { listener.onFault(t); } } } }); }
所以demo要是想listener来完成各种发送结果的处理,使用handler.post方法来处理显示结果的UI
/** * 监听异步调用发送状态接口的响应 * * @author Shaofeng Wang ([email protected]) */ private class StatusSetListener extends AbstractRequestListener<StatusSetResponseBean> { private Context context; private Handler handler; public StatusSetListener(Context context) { this.context = context; this.handler = new Handler(context.getMainLooper()); } @Override public void onRenrenError(RenrenError renrenError) { final int errorCode = renrenError.getErrorCode(); final String errorMsg = renrenError.getMessage(); handler.post(new Runnable() { @Override public void run() { if (StatusPublishActivity.this != null) { publishButton.setEnabled(true); response.setText(errorMsg); if (progress != null) { progress.dismiss(); } } if (errorCode == RenrenError.ERROR_CODE_OPERATION_CANCELLED) { Toast.makeText(context, "发送被取消", Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(context, "发送失败", Toast.LENGTH_SHORT) .show(); } } }); } @Override public void onFault(Throwable fault) { final String errorMsg = fault.toString(); handler.post(new Runnable() { @Override public void run() { if (StatusPublishActivity.this != null) { publishButton.setEnabled(true); response.setText(errorMsg); if (progress != null) { progress.dismiss(); } } Toast.makeText(context, "发送失败", Toast.LENGTH_SHORT).show(); } }); } @Override public void onComplete(StatusSetResponseBean bean) { final String responseStr = bean.toString(); handler.post(new Runnable() { @Override public void run() { if (StatusPublishActivity.this != null) { response.setText(responseStr); publishButton.setEnabled(true); if (progress != null) { progress.dismiss(); } } Toast.makeText(context, "发送成功", Toast.LENGTH_SHORT).show(); } }); } }
这样就异步完成了发送并显示结果的操作
不得不承认这个架构写的很好,很值得在cs结构的android应用中尝试.
但是我们也看到了这个架构的小问题
sdk和demo耦合他密切,如果不知道sdk源码,只靠demo恐怕很难写出发送微博的代码,sdk个人认为应该是封装成几个接口,使用这只管调用,而不是需要两者各种复杂的交互
其实sdk的工作应该是提供一个renren类 里面有各种方法 异步让开发者自己搞就可以了
个人感觉吧,这一点腾讯2.0 和新浪1.0做的都不错