感觉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);
}
这个代码调用了AsyRenren的.publishStatus()方法
我们看一下这个方法
public void publishStatus(StatusSetRequestParam status,
AbstractRequestListener<StatusSetResponseBean> listener,
boolean truncOption) {
StatusHelper helper = new StatusHelper(renren);
helper.asyncPublish(pool, status, listener, truncOption);
}
他生成一个StatusHelper类实例来进行发送操作
/**
* 异步发送状态的方法
*
* @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);
}
}
}
});
}
这个方法是真正的操作发送微博的方法了,而且把结果通过listener传回去
所以demo要是想listener来完成各种发送结果的处理,使用handler.post方法来处理显示结果的UI
/**
* 监听异步调用发送状态接口的响应
*
* @author Shaofeng Wang (shaofeng.wang@renren-inc.com)
*/
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做的都不错