新浪微博客户端开发之授权登录+获取微博列表
闲篇:
最近实在是乱得不行,至于怎么乱我也不知该怎么说,那么久没发博客就证明了这点,一般如果小巫有做详尽的计划,并把时间投入到上面的话,我是可以用最短的时间里把新浪微博客户端给整出来的,但现在进度很慢,我越来越不像个称职的程序猿,因为现在的生活已经不再是代码,更多的是想多享受跟朋友们在一起的快乐。这些话也不多说了,关于这个项目,其实我也头痛了一整子,我很久之前就买了一本李宁的Android应用开发实战,里面很大篇幅就是介绍这个客户端的开发,因为一开始我是比较迷惑的,迷惑他到底有没有使用新浪开发平台提供的SDK,然而整个授权过程到获取微博的各种数据又是怎样的?我还在考虑我要做成一个怎样的,是否只是单纯的模仿呢?反正种种疑虑,一阵子找不到北了。后来我花时间研究了他的代码,慢慢的也找了了一些门道,明白了他从是怎么把整个客户端搭建起来的,他没有使用新浪给我们提供的SDK,而似乎是把SDK的实现给翻出来了,因为SDK仅仅提供了获取微博数据的封装,开发者就只需调用API,知道怎么传参数就行了,所以很多高手是不会直接使用新浪提供的Android SDK。要我从头到尾开发,把所有业务逻辑实现,我实在不行,所以会直接参考Android应用开发实战所提供的代码,把整个新浪微博客户端开发出来给大家看看,这也算是小巫的一个提升,与大家共同进步。
正篇:
本篇博客呢,主要介绍如何进行授权认证,如何获取微博列表,因为代码比较多,我不会全部都能贴出来,整个客户端也没有开发完毕,我也是实现一个功能,然后整理博客发表出来,如果想要项目源码的,可以直接找我,我的QQ:659982592, 如果我在的话,我会尽快答复你的。
先来看看本篇博客想要实现的效果图:
看到以上的效果,我想很多人都想知道是如何实现的,不急,我们慢慢来看,这个可不是能一口吃掉的螃蟹。
我先简单介绍一下以上效果图的业务流程,启动程序后,首先需要获取用户授权,假如已经授权过了,就不会出现提示用户输入登录的界面,授权成功后,直接获取微博数据,显示到微博列表当中。整个流程其实也蛮简单的,现在我们来看看代码。
/Wwj_sina_weibo/src/com/wwj/sina/weibo/WeiboMain.java
这个类用来切换底部标签的,比较高的版本已经不推荐用这种方法实现,不过没关系,反正高版本兼容低版本。
package com.wwj.sina.weibo;
import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
/**
* 主Activity
* @author wwj
* 通过点击RadioGroup下的RadioButton来切换不同界面
*/
@SuppressWarnings("deprecation")
public class WeiboMain extends TabActivity {
public TabHost mTabhost;
public static final String TAB_HOME = "TabHome";
public static final String TAB_MSG = "TabMsg";
public static final String TAB_SELF = "TabSelfInfo";
public static final String TAB_DISCOVE = "TabDiscove";
public static final String TAB_MORE = "TabMore";
RadioButton radio_button0;
public static RadioGroup indexGroup;
@SuppressWarnings("static-access")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置无标题
requestWindowFeature(getWindow().FEATURE_NO_TITLE);
this.setContentView(R.layout.tabbar);
radio_button0 = (RadioButton) this.findViewById(R.id.tabbar_home);
radio_button0.setChecked(true); // 设置首页按钮默认是按下状态
mTabhost = (TabHost) findViewById(android.R.id.tabhost); // 获取TabHost
// 设定标签、制定一个标签作为选项卡指示符
TabSpec tabSpec1 = mTabhost.newTabSpec(TAB_HOME).setIndicator(TAB_HOME);
// 指定一个加载activity的Intent对象作为选项卡内容
tabSpec1.setContent(new Intent(WeiboMain.this, HomeActivity.class));
mTabhost.addTab(tabSpec1); // 添加第一个子页
TabSpec tabSpec2 = mTabhost.newTabSpec(TAB_MSG).setIndicator(TAB_MSG);
tabSpec2.setContent(new Intent(WeiboMain.this, MessageActivity.class));
mTabhost.addTab(tabSpec2); // 添加第二个子页
TabSpec tabSpec3 = mTabhost.newTabSpec(TAB_SELF).setIndicator(TAB_SELF);
tabSpec3.setContent(new Intent(WeiboMain.this, SelfInfoActivity.class));
mTabhost.addTab(tabSpec3); // 添加第三个子页
TabSpec tabSpec4 = mTabhost.newTabSpec(TAB_DISCOVE).setIndicator(
TAB_DISCOVE);
tabSpec4.setContent(new Intent(WeiboMain.this, DiscoveActivity.class));
mTabhost.addTab(tabSpec4); // 添加第四个子页
TabSpec tabSpec5 = mTabhost.newTabSpec(TAB_MORE).setIndicator(TAB_MORE);
tabSpec5.setContent(new Intent(WeiboMain.this, MoreActivity.class));
mTabhost.addTab(tabSpec5); // 添加第一个子页
this.indexGroup = (RadioGroup) this.findViewById(R.id.main_radio);
// 实现RadioGroup的子选项点击监听
indexGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.tabbar_home: // 首页
mTabhost.setCurrentTabByTag(TAB_HOME);
break;
case R.id.tabbar_message:// 信息
mTabhost.setCurrentTabByTag(TAB_MSG);
break;
case R.id.tabbar_me: // 个人资料
mTabhost.setCurrentTabByTag(TAB_SELF);
break;
case R.id.tabbar_discove: // 发现
mTabhost.setCurrentTabByTag(TAB_DISCOVE);
break;
case R.id.tabbar_more: // 更多
mTabhost.setCurrentTabByTag(TAB_MORE);
}
}
});
}
}
/Wwj_sina_weibo/src/com/wwj/sina/weibo/HomeActivity.java
这个Activity就是显示微博列表的界面,代码还不完善,这里只看关键点。
package com.wwj.sina.weibo;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.weibo.net.Weibo;
import com.wwj.sina.weibo.adapter.WeiboListAdapter;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.library.StorageManager;
import com.wwj.sina.weibo.library.WeiboData;
import com.wwj.sina.weibo.library.WeiboManager;
import com.wwj.sina.weibo.listener.impl.StatusRequestListenerImpl;
import com.wwj.sina.weibo.object.Status;
import com.wwj.sina.weibo.object.User;
import com.wwj.sina.weibo.util.Tools;
import com.wwj.sina.weibo.view.PullToRefreshListView;
import com.wwj.sina.weibo.view.PullToRefreshListView.OnRefreshListener;
import com.wwj.sina.weibo.workqueue.DoneAndProcess;
import com.wwj.sina.weibo.workqueue.WorkQueueMonitor;
import com.wwj.sina.weibo.workqueue.task.ParentTask;
import com.wwj.sina.weibo.workqueue.task.PullFileTask;
/**
* 主界面
*
* @author wwj 用于显示公共微博
*/
public class HomeActivity extends Activity implements Const, OnClickListener,
OnItemClickListener, OnItemLongClickListener, OnMenuItemClickListener,
DoneAndProcess {
public PullToRefreshListView weiboListView; // 自定义ListView
private Weibo weibo; // 微博对象
public HomeData homeData; // 主界面数据
public TextView username; // 用户名,显示在标题栏
public Button btn_post_weibo; // 发布微博
public Button btn_reload; // 加载新微博
private LinearLayout linearLayoutHome;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
};
};
// 微博列表主界面的数据
public static class HomeData {
public WeiboListAdapter weiboListAdapter;
public WorkQueueMonitor imageWorkQueueMonitor;
public WorkQueueMonitor taskWorkQueueMonitor;
public User user;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
loadView();
getWindow().setBackgroundDrawable(null);
weibo = Tools.getWeibo(this); // 获取微博对象
homeData = (HomeData) getLastNonConfigurationInstance();
if (homeData == null) {
homeData = new HomeData();
if (!(weibo == null || !weibo.isSessionValid())) {
@SuppressWarnings("unchecked")
List<Status> statuses = StorageManager.loadList(this,
Const.HOME);
if (statuses == null) {
statuses = WeiboManager.getHomeTimeline(this);
}
homeData.weiboListAdapter = WeiboData.loadWeiboListData(this,
Const.HOME, weiboListView, statuses);
}
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public Object onRetainNonConfigurationInstance() {
return homeData;
}
// 加载视图
private void loadView() {
weiboListView = (PullToRefreshListView) findViewById(R.id.weibolist);
linearLayoutHome = (LinearLayout) findViewById(R.id.ll_home_layout);
username = (TextView) this.findViewById(R.id.tv_home_name);
btn_post_weibo = (Button) this.findViewById(R.id.btn_home_post_weibo);
btn_reload = (Button) this.findViewById(R.id.btn_home_reload);
weiboListView.setOnItemClickListener(this);
btn_post_weibo.setOnClickListener(this);
btn_reload.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = null;
GlobalObject globalObject = Tools.getGlobalObject(this);
switch (v.getId()) {
case R.id.btn_home_post_weibo: // 发布微博
intent = new Intent(HomeActivity.this, PostWeibo.class);
startActivity(intent);
break;
case R.id.btn_home_reload: // 刷新列表
long sinceId = homeData.weiboListAdapter.getMaxId() + 1;
WeiboManager.getHomeTimeline(this, sinceId, 0,
DEFAULT_STATUS_COUNT, true, new StatusRequestListenerImpl(
this, linearLayoutHome, HOME));
View homeReloadAnim = findViewById(R.id.pb_home_reload);
View homeReload = findViewById(R.id.btn_home_reload);
homeReloadAnim.setVisibility(View.VISIBLE);
homeReload.setVisibility(View.GONE);
break;
}
}
@Override
public void doneProcess(ParentTask task) {
Message msg = new Message();
msg.obj = task;
if (task instanceof PullFileTask) {
msg.what = HANDLER_TYPE_LOAD_PROFILE_IMAGE;
msg.obj = ((PullFileTask) task).fileUrl;
}
handler.sendMessage(msg);
}
@Override
public boolean onMenuItemClick(MenuItem item) {
return false;
}
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
return false;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent intent = null;
switch (parent.getId()) {
case R.id.weibolist:
// 按更多项
// 注意:更多点击的位置
if (position == homeData.weiboListAdapter.getCount()) {
long maxId = homeData.weiboListAdapter.getMinId() - 1;
WeiboManager.getHomeTimeline(this, 0, maxId,
DEFAULT_STATUS_COUNT, true,
new StatusRequestListenerImpl(this, linearLayoutHome,
HOME));
homeData.weiboListAdapter.showMoreAnim();
} else { // 点击列表项
Status status = homeData.weiboListAdapter.getStatus(position);
if (status != null) {
intent = new Intent(this, WeiboViewer.class);
WeiboViewer.status = status;
startActivity(intent);
}
}
break;
}
}
}
上面使用到一个Tools类,这是一个工具类,用来获取微博对象和一些转换操作,稍微看一下
/Wwj_sina_weibo/src/com/wwj/sina/weibo/util/Tools.java
package com.wwj.sina.weibo.util;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.ImageView;
import com.weibo.net.Weibo;
import com.wwj.sina.weibo.GlobalObject;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.library.FaceMan;
public class Tools implements Const {
/**
* 获取微博对象
* @param activity
* @return
*/
public static Weibo getWeibo(Activity activity) {
GlobalObject globalObject = (GlobalObject) activity
.getApplicationContext();
return globalObject.getWeibo(activity);
}
/**
* 判断当前是否有微博对象
* @param activity
* @return
*/
public static boolean hasWeibo(Activity activity) {
GlobalObject globalObject = (GlobalObject) activity
.getApplicationContext();
return globalObject.getWeibo() == null ? false : true;
}
public static GlobalObject getGlobalObject(Activity activity) {
GlobalObject globalObject = (GlobalObject) activity
.getApplicationContext();
return globalObject;
}
// 将微博的日期字符串转换为Date对象
public static Date strToDate(String str) {
// sample:Tue May 31 17:46:55 +0800 2011
// E:周 MMM:字符串形式的月,如果只有两个M,表示数值形式的月 Z表示时区(+0800)
SimpleDateFormat sdf = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy",
Locale.US);
Date result = null;
try {
result = sdf.parse(str);
} catch (Exception e) {
// TODO: handle exception
}
return result;
}
public static void dataTransfer(InputStream is, OutputStream os) {
byte[] buffer = new byte[8192];
int count = 0;
try {
while((count = is.read(buffer)) > -1) {
os.write(buffer, 0, count);
}
} catch (Exception e) {
}
}
public static void userVerified(ImageView imageView, int verifiedType) {
if (verifiedType >= 0) {
imageView.setVisibility(View.VISIBLE);
switch (verifiedType) {
case 0:
case 220:
imageView.setImageLevel(verifiedType);
break;
default:
imageView.setImageLevel(1);
break;
}
}
}
public static SpannableString changeTextToFace(Context context,
Spanned spanned) {
String text = spanned.toString();
SpannableString spannableString = new SpannableString(spanned);
Pattern pattern = Pattern.compile("\\[[^\\]]+\\]");
Matcher matcher = pattern.matcher(text);
boolean b = true;
while (b = matcher.find()) {
String faceText = text.substring(matcher.start(), matcher.end());
int resourceId = FaceMan.getResourceId(faceText);
if (resourceId > 0) {
Bitmap bitmap = BitmapFactory.decodeResource(
context.getResources(), resourceId);
ImageSpan imageSpan = new ImageSpan(bitmap);
spannableString.setSpan(imageSpan, matcher.start(),
matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return spannableString;
}
public static String atBlue(String s) {
StringBuilder sb = new StringBuilder();
int commonTextColor = Color.BLACK;
int signColor = Color.BLUE;
int state = 1;
String str = "";
for (int i = 0; i < s.length(); i++) {
switch (state) {
case 1: // 普通字符状态
// 遇到@
if (s.charAt(i) == '@') {
state = 2;
str += s.charAt(i);
}
// 遇到#
else if (s.charAt(i) == '#') {
str += s.charAt(i);
state = 3;
}
// 添加普通字符
else {
if (commonTextColor == Color.BLACK)
sb.append(s.charAt(i));
else
sb.append("<font color='" + commonTextColor + "'>"
+ s.charAt(i) + "</font>");
}
break;
case 2: // 处理遇到@的情况
// 处理@后面的普通字符
if (Character.isJavaIdentifierPart(s.charAt(i))) {
str += s.charAt(i);
}
else {
// 如果只有一个@,作为普通字符处理
if ("@".equals(str)) {
sb.append(str);
}
// 将@及后面的普通字符变成蓝色
else {
sb.append(setTextColor(str, String.valueOf(signColor)));
}
// @后面有#的情况,首先应将#添加到str里,这个值可能会变成蓝色,也可以作为普通字符,要看后面还有没有#了
if (s.charAt(i) == '#') {
str = String.valueOf(s.charAt(i));
state = 3;
}
// @后面还有个@的情况,和#类似
else if (s.charAt(i) == '@') {
str = String.valueOf(s.charAt(i));
state = 2;
}
// @后面有除了@、#的其他特殊字符。需要将这个字符作为普通字符处理
else {
if (commonTextColor == Color.BLACK)
sb.append(s.charAt(i));
else
sb.append("<font color='" + commonTextColor + "'>"
+ s.charAt(i) + "</font>");
state = 1;
str = "";
}
}
break;
case 3: // 处理遇到#的情况
// 前面已经遇到一个#了,这里处理结束的#
if (s.charAt(i) == '#') {
str += s.charAt(i);
sb.append(setTextColor(str, String.valueOf(signColor)));
str = "";
state = 1;
}
// 如果#后面有@,那么看一下后面是否还有#,如果没有#,前面的#作废,按遇到@处理
else if (s.charAt(i) == '@') {
if (s.substring(i).indexOf("#") < 0) {
sb.append(str);
str = String.valueOf(s.charAt(i));
state = 2;
} else {
str += s.charAt(i);
}
}
// 处理#...#之间的普通字符
else {
str += s.charAt(i);
}
break;
}
}
if (state == 1 || state == 3) {
sb.append(str);
} else if (state == 2) {
if ("@".equals(str)) {
sb.append(str);
} else {
sb.append(setTextColor(str, String.valueOf(signColor)));
}
}
return sb.toString();
}
public static String setTextColor(String s, String color) {
String result = "<font color='" + color + "'>" + s + "</font>";
return result;
}
public static String getTimeStr(Date oldTime, Date currentDate) {
long time1 = currentDate.getTime();
long time2 = oldTime.getTime();
long time = (time1 - time2) / 1000;
if (time >= 0 && time < 60) {
return "刚才";
} else if (time >= 60 && time < 3600) {
return time / 60 + "分钟前";
} else if (time >= 3600 && time < 3600 * 24) {
return time / 3600 + "小时前";
} else {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
return sdf.format(oldTime);
}
}
}
上面定义了一个getWeibo()的方法,可以看到它是通过GlobalObject来获取微博对象的,那在看看这个类
/Wwj_sina_weibo/src/com/wwj/sina/weibo/GlobalObject.java
package com.wwj.sina.weibo;
import android.app.Activity;
import android.app.Application;
import com.weibo.net.Weibo;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.listener.AuthDialogListener;
import com.wwj.sina.weibo.net.PullFile;
import com.wwj.sina.weibo.object.Consumer;
import com.wwj.sina.weibo.workqueue.WorkQueueMonitor;
import com.wwj.sina.weibo.workqueue.WorkQueueStorage;
public class GlobalObject extends Application implements Const{
private Weibo weibo;
private WorkQueueStorage workQueueStorage;
private WorkQueueMonitor imageWorkQueueMonitor;
private WorkQueueMonitor taskWorkQueueMonitor;
public Weibo getWeibo(Activity activity) {
if (weibo == null || !weibo.isSessionValid()) {
weibo = Weibo.getInstance(); // 获取Weibo对象
weibo.setupConsumerConfig(Consumer.consumerKey, Consumer.consumerSecret);
weibo.setRedirectUrl(Consumer.redirectUrl);
weibo.authorize(activity, new AuthDialogListener(activity));
}
return weibo;
}
public Weibo getWeibo() {
return weibo;
}
public WorkQueueStorage getWorkQueueStorage() {
if (workQueueStorage == null){
workQueueStorage = new WorkQueueStorage();
}
return workQueueStorage;
}
public WorkQueueMonitor getWorkQueueMonitor(Activity activity) {
if (imageWorkQueueMonitor == null) {
imageWorkQueueMonitor = new WorkQueueMonitor(activity, getWorkQueueStorage(), new PullFile(), MONITOR_TYPE_IMAGE);
imageWorkQueueMonitor.start();
}
return imageWorkQueueMonitor;
}
}
可以看到这个类是Application级别的,说明最先加载的是这个类,来看这个类定义的getWeibo()方法,现在很直观啦,这里就是获取授权认证的地方。设置好consumerKey和consumerSecret后,就可以调用authorize()方法进行授权了。这个方法在Weibo这个类当中,这个类很重要,能不能使用微博功能就看它了。
/Wwj_sina_weibo/src/com/weibo/net/Weibo.java
/*
* Copyright 2011 Sina.
*
* Licensed under the Apache License and Weibo License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.open.weibo.com
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.weibo.net;
import java.io.IOException;
import java.net.MalformedURLException;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.CookieSyncManager;
/**
* Encapsulation main Weibo APIs, Include: 1. getRquestToken , 2.
* getAccessToken, 3. url request. Used as a single instance class. Implements a
* weibo api as a synchronized way.
*
* @author ZhangJie (zhangjie2@staff.sina.com.cn)
*/
public class Weibo {
// public static String SERVER = "http://api.t.sina.com.cn/";
public static String SERVER = "https://api.weibo.com/2/";
public static String URL_OAUTH_TOKEN = "http://api.t.sina.com.cn/oauth/request_token";
public static String URL_AUTHORIZE = "http://api.t.sina.com.cn/oauth/authorize";
public static String URL_ACCESS_TOKEN = "http://api.t.sina.com.cn/oauth/access_token";
public static String URL_AUTHENTICATION = "http://api.t.sina.com.cn/oauth/authenticate";
public static String URL_OAUTH2_ACCESS_TOKEN = "https://api.weibo.com/oauth2/access_token";
// public static String URL_OAUTH2_ACCESS_AUTHORIZE =
// "http://t.weibo.com:8093/oauth2/authorize";
public static String URL_OAUTH2_ACCESS_AUTHORIZE = "https://api.weibo.com/oauth2/authorize";
private static String APP_KEY = "";
private static String APP_SECRET = "";
private static Weibo mWeiboInstance = null;
private Token mAccessToken = null;
private RequestToken mRequestToken = null;
private WeiboDialogListener mAuthDialogListener;
private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32973;
public static final String TOKEN = "access_token";
public static final String EXPIRES = "expires_in";
public static final String DEFAULT_REDIRECT_URI = "wbconnect://success";// 暂不支持
public static final String DEFAULT_CANCEL_URI = "wbconnect://cancel";// 暂不支持
private String mRedirectUrl;
private Weibo() {
Utility.setRequestHeader("Accept-Encoding", "gzip");
Utility.setTokenObject(this.mRequestToken);
mRedirectUrl = DEFAULT_REDIRECT_URI;
}
/**
* 获取单例
* @return
*/
public synchronized static Weibo getInstance() {
if (mWeiboInstance == null) {
mWeiboInstance = new Weibo();
}
return mWeiboInstance;
}
// 设置accessToken
public void setAccessToken(AccessToken token) {
mAccessToken = token;
}
public Token getAccessToken() {
return this.mAccessToken;
}
/**
* 设置第三方key和secret
* @param consumer_key
* @param consumer_secret
*/
public void setupConsumerConfig(String consumer_key, String consumer_secret) {
Weibo.APP_KEY = consumer_key;
Weibo.APP_SECRET = consumer_secret;
}
public static String getAppKey() {
return Weibo.APP_KEY;
}
public static String getAppSecret() {
return Weibo.APP_SECRET;
}
public void setRequestToken(RequestToken token) {
this.mRequestToken = token;
}
public static String getSERVER() {
return SERVER;
}
public static void setSERVER(String sERVER) {
SERVER = sERVER;
}
// 设置oauth_verifier
public void addOauthverifier(String verifier) {
mRequestToken.setVerifier(verifier);
}
public String getRedirectUrl() {
return mRedirectUrl;
}
/**
* 设置第三方回调页
* @param mRedirectUrl
*/
public void setRedirectUrl(String mRedirectUrl) {
this.mRedirectUrl = mRedirectUrl;
}
/**
* Requst sina weibo open api by get or post
*
* @param url
* Openapi request URL.
* @param params
* http get or post parameters . e.g.
* gettimeling?max=max_id&min=min_id max and max_id is a pair of
* key and value for params, also the min and min_id
* @param httpMethod
* http verb: e.g. "GET", "POST", "DELETE"
* @throws IOException
* @throws MalformedURLException
* @throws WeiboException
*/
public String request(Context context, String url, WeiboParameters params, String httpMethod,
Token token) throws WeiboException {
String rlt = Utility.openUrl(context, url, httpMethod, params, this.mAccessToken);
return rlt;
}
/**/
public RequestToken getRequestToken(Context context, String key, String secret,
String callback_url) throws WeiboException {
Utility.setAuthorization(new RequestTokenHeader());
WeiboParameters postParams = new WeiboParameters();
postParams.add("oauth_callback", callback_url);
String rlt;
rlt = Utility.openUrl(context, Weibo.URL_OAUTH_TOKEN, "POST", postParams, null);
RequestToken request = new RequestToken(rlt);
this.mRequestToken = request;
return request;
}
public AccessToken generateAccessToken(Context context, RequestToken requestToken)
throws WeiboException {
Utility.setAuthorization(new AccessTokenHeader());
WeiboParameters authParam = new WeiboParameters();
authParam.add("oauth_verifier", this.mRequestToken.getVerifier()/* "605835" */);
authParam.add("source", APP_KEY);
String rlt = Utility.openUrl(context, Weibo.URL_ACCESS_TOKEN, "POST", authParam,
this.mRequestToken);
AccessToken accessToken = new AccessToken(rlt);
this.mAccessToken = accessToken;
return accessToken;
}
public AccessToken getXauthAccessToken(Context context, String app_key, String app_secret,
String usrname, String password) throws WeiboException {
Utility.setAuthorization(new XAuthHeader());
WeiboParameters postParams = new WeiboParameters();
postParams.add("x_auth_username", usrname);
postParams.add("x_auth_password", password);
postParams.add("oauth_consumer_key", APP_KEY);
String rlt = Utility.openUrl(context, Weibo.URL_ACCESS_TOKEN, "POST", postParams, null);
AccessToken accessToken = new AccessToken(rlt);
this.mAccessToken = accessToken;
return accessToken;
}
/**
* 获取Oauth2.0的accesstoken
*
* https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&
* client_secret=YOUR_CLIENT_SECRET&grant_type=password&redirect_uri=
* YOUR_REGISTERED_REDIRECT_URI&username=USER_NAME&pasword=PASSWORD
*
* @param context
* @param app_key
* @param app_secret
* @param usrname
* @param password
* @return
* @throws WeiboException
*/
public Oauth2AccessToken getOauth2AccessToken(Context context, String app_key,
String app_secret, String usrname, String password) throws WeiboException {
Utility.setAuthorization(new Oauth2AccessTokenHeader());
WeiboParameters postParams = new WeiboParameters();
postParams.add("username", usrname);
postParams.add("password", password);
postParams.add("client_id", app_key);
postParams.add("client_secret", app_secret);
postParams.add("grant_type", "password");
String rlt = Utility.openUrl(context, Weibo.URL_OAUTH2_ACCESS_TOKEN, "POST", postParams,
null);
Oauth2AccessToken accessToken = new Oauth2AccessToken(rlt);
this.mAccessToken = accessToken;
return accessToken;
}
/**
* Share text content or image to weibo .
*
*/
public boolean share2weibo(Activity activity, String accessToken, String tokenSecret,
String content, String picPath) throws WeiboException {
if (TextUtils.isEmpty(accessToken)) {
throw new WeiboException("token can not be null!");
}
// else if (TextUtils.isEmpty(tokenSecret)) {
// throw new WeiboException("secret can not be null!");
// }
if (TextUtils.isEmpty(content) && TextUtils.isEmpty(picPath)) {
throw new WeiboException("weibo content can not be null!");
}
Intent i = new Intent(activity, ShareActivity.class);
i.putExtra(ShareActivity.EXTRA_ACCESS_TOKEN, accessToken);
i.putExtra(ShareActivity.EXTRA_TOKEN_SECRET, tokenSecret);
i.putExtra(ShareActivity.EXTRA_WEIBO_CONTENT, content);
i.putExtra(ShareActivity.EXTRA_PIC_URI, picPath);
activity.startActivity(i);
return true;
}
private boolean startSingleSignOn(Activity activity, String applicationId,
String[] permissions, int activityCode) {
return false;
}
public static boolean flag = false;
private void startDialogAuth(Activity activity, String[] permissions) {
if(flag == true) return;
WeiboParameters params = new WeiboParameters();
if (permissions.length > 0) {
params.add("scope", TextUtils.join(",", permissions));
}
CookieSyncManager.createInstance(activity);
dialog(activity, params, new WeiboDialogListener() {
public void onComplete(Bundle values) {
flag = false;
// ensure any cookies set by the dialog are saved
CookieSyncManager.getInstance().sync();
if (null == mAccessToken) {
mAccessToken = new Token();
}
mAccessToken.setToken(values.getString(TOKEN));
mAccessToken.setExpiresIn(values.getString(EXPIRES));
if (isSessionValid()) {
Log.d("Weibo-authorize",
"Login Success! access_token=" + mAccessToken.getToken() + " expires="
+ mAccessToken.getExpiresIn());
mAuthDialogListener.onComplete(values);
} else {
Log.d("Weibo-authorize", "Failed to receive access token");
mAuthDialogListener.onWeiboException(new WeiboException(
"Failed to receive access token."));
}
}
public void onError(DialogError error) {
flag = false;
Log.d("Weibo-authorize", "Login failed: " + error);
mAuthDialogListener.onError(error);
}
public void onWeiboException(WeiboException error) {
flag = false;
Log.d("Weibo-authorize", "Login failed: " + error);
mAuthDialogListener.onWeiboException(error);
}
public void onCancel() {
flag = false;
Log.d("Weibo-authorize", "Login canceled");
mAuthDialogListener.onCancel();
}
});
flag = true;
}
/**
* User-Agent Flow
*
* @param activity
*
* @param listener
* 授权结果监听器
*/
public void authorize(Activity activity, final WeiboDialogListener listener) {
authorize(activity, new String[] {}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
}
@SuppressWarnings("unused")
private void authorize(Activity activity, String[] permissions,
final WeiboDialogListener listener) {
authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
}
private void authorize(Activity activity, String[] permissions, int activityCode,
final WeiboDialogListener listener) {
Utility.setAuthorization(new Oauth2AccessTokenHeader());
boolean singleSignOnStarted = false;
mAuthDialogListener = listener;
// Prefer single sign-on, where available.
if (activityCode >= 0) {
singleSignOnStarted = startSingleSignOn(activity, APP_KEY, permissions, activityCode);
}
// Otherwise fall back to traditional dialog.
if (!singleSignOnStarted) {
startDialogAuth(activity, permissions);
}
}
@SuppressWarnings("unused")
private void authorizeCallBack(int requestCode, int resultCode, Intent data) {
}
public void dialog(Context context, WeiboParameters parameters,
final WeiboDialogListener listener) {
parameters.add("client_id", APP_KEY);
parameters.add("response_type", "token");
parameters.add("redirect_uri", mRedirectUrl);
parameters.add("display", "mobile");
if (isSessionValid()) {
parameters.add(TOKEN, mAccessToken.getToken());
}
String url = URL_OAUTH2_ACCESS_AUTHORIZE + "?" + Utility.encodeUrl(parameters);
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
Utility.showAlert(context, "Error",
"Application requires permission to access the Internet");
} else {
new WeiboDialog(this, context, url, listener).show();
}
}
public boolean isSessionValid() {
if (mAccessToken != null) {
return (!TextUtils.isEmpty(mAccessToken.getToken()) && (mAccessToken.getExpiresIn() == 0 || (System
.currentTimeMillis() < mAccessToken.getExpiresIn())));
}
return false;
}
}
你们自己找到authorize()看看呗,怎么弹出那个登录界面的自己研究去,这个方法需要传入一个listener,
就是这个类了AuthDialogListener
/Wwj_sina_weibo/src/com/wwj/sina/weibo/listener/AuthDialogListener.java
授权完成后,回调这个类的onComplete方法,然后就可以获取微博数据了。
package com.wwj.sina.weibo.listener;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.weibo.net.DialogError;
import com.weibo.net.WeiboDialogListener;
import com.weibo.net.WeiboException;
import com.wwj.sina.weibo.HomeActivity;
import com.wwj.sina.weibo.adapter.WeiboListAdapter;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.library.StorageManager;
import com.wwj.sina.weibo.library.WeiboData;
import com.wwj.sina.weibo.library.WeiboManager;
import com.wwj.sina.weibo.object.User;
import com.wwj.sina.weibo.util.SettingUtil;
public class AuthDialogListener implements WeiboDialogListener {
private Activity activity;
public AuthDialogListener(Activity activity) {
super();
this.activity = activity;
}
public void onComplete(Bundle values) {
// 保存access_token 和 expires_in
String token = values.getString("access_token");
String expires_in = values.getString("expires_in");
SettingUtil.set(activity, SettingUtil.ACCESS_TOKEN, token);
SettingUtil.set(activity, SettingUtil.EXPIRES_IN, expires_in);
Toast.makeText(activity, "认证成功", Toast.LENGTH_SHORT).show();
HomeActivity homeActivity = (HomeActivity) activity;
WeiboListAdapter weiboListAdapter = null;
long uid = Long.parseLong(values.getString("uid"));
User user = WeiboManager.getUser(activity, uid);
if (user != null) {
homeActivity.username.setText(user.name);
StorageManager.setValue(activity, "uid", uid); // 保存用户UID
}
weiboListAdapter = WeiboData.loadWeiboListData(activity, Const.HOME,
homeActivity.weiboListView);
homeActivity.homeData.weiboListAdapter = weiboListAdapter;
}
public void onWeiboException(WeiboException e) {
// 当认证过程中捕获到WeiboException时调用
Toast.makeText(activity, "Auth exception:" + e.getMessage(),
Toast.LENGTH_LONG).show();
}
public void onError(DialogError e) {
// Oauth2.0认证过程中,当认证对话框中的webView接收数据出现错误时调用此方法
Toast.makeText(activity, "Auth error:" + e.getMessage(),
Toast.LENGTH_LONG).show();
}
public void onCancel() {
// Oauth2.0认证过程中,如果认证窗口被关闭或认证取消时调用
Toast.makeText(activity, "Auth cancel", Toast.LENGTH_LONG).show();
}
}
执行完这个就已经把数据显示出来了
WeiboData.loadWeiboListData(activity, Const.HOME,homeActivity.weiboListView);
这里又有一个WeiboData这个类,看看就明白了
package com.wwj.sina.weibo.library;
import java.util.List;
import android.app.Activity;
import android.widget.ListView;
import com.wwj.sina.weibo.adapter.WeiboListAdapter;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.object.Status;
import com.wwj.sina.weibo.util.Tools;
public class WeiboData implements Const {
public static WeiboListAdapter loadWeiboListData(Activity activity,
int type, ListView listView) {
return loadWeiboListData(activity, type, listView, null);
}
public static WeiboListAdapter loadWeiboListData(Activity activity,
int type, ListView listView, List<Status> statuses) {
WeiboListAdapter adapter = null;
if (Tools.hasWeibo(activity)) {
switch (type) {
case HOME:
if (statuses == null)
statuses = WeiboManager.getHomeTimeline(activity);
adapter = new WeiboListAdapter(activity, statuses, type);
break;
default:
break;
}
listView.setAdapter(adapter);
}
return adapter;
}
}
可以看到,这里ListView就直接setAdapter了。来看到第二个loadWeiboListData方法,有一个List<Status> statuses参数,这个就是保存微博数据的参数了,是怎么得到的?我们又可以看到一个类WeiboManager里有一个getHomeTimeline的方法,这个就是返回微博数据的方法。
等不及了,进去看看。
/Wwj_sina_weibo/src/com/wwj/sina/weibo/library/WeiboManager.java
package com.wwj.sina.weibo.library;
import java.io.File;
import java.util.List;
import android.app.Activity;
import com.weibo.net.AsyncWeiboRunner;
import com.weibo.net.AsyncWeiboRunner.RequestListener;
import com.weibo.net.Weibo;
import com.weibo.net.WeiboParameters;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.object.Consumer;
import com.wwj.sina.weibo.object.Status;
import com.wwj.sina.weibo.object.User;
import com.wwj.sina.weibo.util.Tools;
import com.wwj.sina.weibo.workqueue.DoneAndProcess;
import com.wwj.sina.weibo.workqueue.WorkQueueStorage;
import com.wwj.sina.weibo.workqueue.task.PullFileTask;
/**
* 微博管理类,提供方法获取微博数据
*
* @author Administrator
*
*/
public class WeiboManager implements Const {
public static List<Status> getHomeTimeline(Activity activity) {
return getHomeTimeline(activity, 0, 0, DEFAULT_STATUS_COUNT);
}
private static List<Status> getHomeTimeline(Activity activity,
long sinceId, long maxId, int count) {
return getHomeTimeline(activity, sinceId, maxId, count, false, null);
}
/**
* 获取当前登录用户及其所关注用户的最新微博
*
* @param activity
* @param sinceId
* @param maxId
* @param count
* @param async
* 是否同步
* @param listener
* @return
*/
@SuppressWarnings("unchecked")
public static List<Status> getHomeTimeline(Activity activity,
long sinceId, long maxId, int count, boolean async,
RequestListener listener) {
// 访问接口url
String url = Weibo.SERVER + "statuses/home_timeline.json";
// 获取微博对象
Weibo weibo = Tools.getWeibo(activity);
if (weibo == null || !weibo.isSessionValid()) {
return null;
}
WeiboParameters bundle = new WeiboParameters();
bundle.add("source", Consumer.consumerKey);
if (sinceId != 0)
bundle.add("since_id", String.valueOf(sinceId));
if (maxId != 0)
bundle.add("max_id", String.valueOf(maxId));
if (count != 0)
bundle.add("count", String.valueOf(count));
List<Status> statuses = null;
try {
if (!async) {
// 请求获取JSON数据
String json = weibo.request(activity, url, bundle, "GET",
weibo.getAccessToken());
statuses = JSONAndObject
.convert(Status.class, json, "statuses");
} else {
AsyncWeiboRunner asyncWeiboRunner = new AsyncWeiboRunner(weibo);
asyncWeiboRunner
.request(activity, url, bundle, "GET", listener);
}
} catch (Exception e) {
}
return statuses;
}
public static String getImageurl(Activity activity, String url) {
return getImageurl(activity, url, null);
}
public static String getImageurl(Activity activity, String url,
DoneAndProcess doneAndProcess) {
String result = null;
if (url == null || "".equals(url))
return result;
result = PATH_FILE_CACHE + "/" + url.hashCode();
File file = new File(PATH_FILE_CACHE + "/" + url.hashCode());
if (file.exists()) {
return result;
} else {
WorkQueueStorage workQueueStorage = Tools.getGlobalObject(activity)
.getWorkQueueStorage();
if (workQueueStorage != null) {
if (doneAndProcess == null) {
workQueueStorage.addDoneWebFileUrl(url);
} else {
PullFileTask pullFileTask = new PullFileTask();
pullFileTask.doneAndProcess = doneAndProcess;
pullFileTask.fileUrl = url;
workQueueStorage.addTask(pullFileTask);
}
}
result = null;
}
return result;
}
public static boolean hasPicture(Status status) {
if (status.thumbnail_pic != null && !"".equals(status.thumbnail_pic))
return true;
if (status.retweeted_status != null) {
if (status.retweeted_status.thumbnail_pic != null
&& !"".equals(status.retweeted_status.thumbnail_pic)) {
return true;
}
}
return false;
}
public static User getUser(Activity activity, long uid) {
return getUser(activity, uid, null, false, null);
}
public static User getUser(Activity activity, String screen_name) {
return getUser(activity, 0, screen_name, false, null);
}
public static User getUser(Activity activity, long uid, String screen_name,
boolean async, RequestListener listener) {
String url = Weibo.SERVER + "users/show.json";
Weibo weibo = Tools.getWeibo(activity);
if (weibo == null || !weibo.isSessionValid()) {
return null;
}
User user = null;
WeiboParameters bundle = new WeiboParameters();
bundle.add("source", Consumer.consumerKey);
if (uid > 0) {
bundle.add("uid", String.valueOf(uid));
} else if (screen_name != null) {
bundle.add("screen_name", screen_name);
} else {
return user;
}
try {
if (!async) {
String json = weibo.request(activity, url, bundle, "GET",
weibo.getAccessToken());
user = new User();
JSONAndObject.convertSingleObject((Object) user, json);
} else {
AsyncWeiboRunner asyncWeiboRunner = new AsyncWeiboRunner(weibo);
asyncWeiboRunner
.request(activity, url, bundle, "GET", listener);
}
} catch (Exception e) {
}
return user;
}
}
只看 getHomeTimeline()这个方法,一直追踪,很快就可以知道这个微博数据是怎么得到的了。
public static List<Status> getHomeTimeline(Activity activity,
long sinceId, long maxId, int count, boolean async,
RequestListener listener) {
// 访问接口url
String url = Weibo.SERVER + "statuses/home_timeline.json";
// 获取微博对象
Weibo weibo = Tools.getWeibo(activity);
if (weibo == null || !weibo.isSessionValid()) {
return null;
}
WeiboParameters bundle = new WeiboParameters();
bundle.add("source", Consumer.consumerKey);
if (sinceId != 0)
bundle.add("since_id", String.valueOf(sinceId));
if (maxId != 0)
bundle.add("max_id", String.valueOf(maxId));
if (count != 0)
bundle.add("count", String.valueOf(count));
List<Status> statuses = null;
try {
if (!async) {
// 请求获取JSON数据
String json = weibo.request(activity, url, bundle, "GET",
weibo.getAccessToken());
statuses = JSONAndObject
.convert(Status.class, json, "statuses");
} else {
AsyncWeiboRunner asyncWeiboRunner = new AsyncWeiboRunner(weibo);
asyncWeiboRunner
.request(activity, url, bundle, "GET", listener);
}
} catch (Exception e) {
}
return statuses;
}
就是这个方法了,通过调用weibo对象的request()方法,返回Json字符串,通过解析得到的JSON字符串得到statuses数组。这里需要进行的转换,全靠JSONAndObject这个类
package com.wwj.sina.weibo.library;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import android.util.Log;
import com.wwj.sina.weibo.interfaces.WeiboObject;
public class JSONAndObject {
/**
* 将一个对象转换为JSON格式的字符串,只转换public类型的变量
*
* @param obj
* @return
*/
public static String convertSingleObjectToJson(Object obj) {
String json = null;
if (obj == null) {
return json;
}
Field[] fields = obj.getClass().getFields();
json = "{";
// 开始转换每一个public类型的变量
for (int i = 0; i < fields.length; i++) {
try {
Field field = fields[i];
if (field.getType() == String.class) {
// 属性值为null, 用空字符串取代
String temp = ((field.get(obj) == null) ? "" : String
.valueOf(field.get(obj)));
// 处理字符串中的双引号
// JSON字符串中不能直接使用双引号
temp = temp.replaceAll("\"", "\\\\\"");
json += "\"" + field.getName() + "\":\"" + temp + "\"";
}
// long类型
else if (field.getType() == long.class) {
json += "\"" + field.getName() + "\":" + field.getLong(obj);
}
// int类型
else if (field.getType() == int.class) {
json += "\"" + field.getName() + "\":" + field.getInt(obj);
}
// boolean类型
else if (field.getType() == boolean.class) {
json += "\"" + field.getName() + "\":"
+ field.getBoolean(obj);
}
// Object类型(WeiboObject类型)
else {
Object fieldObject = field.get(obj);
if (fieldObject instanceof WeiboObject) {
// 如果对象中含有对象类型的变量
// 递归生成JSON字符串
json += "\"" + field.getName() + "\":"
+ convertSingleObjectToJson(fieldObject);
} else {
continue;
}
}
if (i < fields.length - 1) {
json += ",";
}
} catch (Exception e) {
}
}
json += "}";
return json;
}
/**
* 将obj转换为JSON字符串,该字符串必须是一个对象 其中obj必须是一个List,而且JSON字符串必须包含一个propertyName
* 制定的属性,属性值是JSON数组,该数组与obj指定的List对应 类似于hometimeline.json返回的JSON字符串的逆过程
*
* @param obj
* @param propertyName
* @return
*/
public static String covertObjectToJson(Object obj, String propertyName) {
String json = null;
if (obj == null) {
return json;
}
if (obj instanceof List) {
List list = (List) obj;
if (propertyName != null) {
// 包含一个属性的对象,这个属性是对象数组
json = "{\"" + propertyName + "\":[";
} else {
// 对象数组
json = "[";
}
for (int i = 0; i < list.size(); i++) {
Object item = list.get(i);
json += convertSingleObjectToJson(item);
if (i < list.size() - 1)
json += ",";
}
if (propertyName != null) {
json += "]}";
} else {
json = "]";
}
}
return json;
}
/**
* 将json字符串转换为List
*
* @param c
* @param json
* @param propertyName
* 这个参数用来制定属性的对象,而且这个属性值必须是一个数组
* @return
*/
public static List convert(Class c, String json, String propertyName) {
List objs = null;
if (c == null || json == null)
return objs;
try {
// 只使用public类型字段
Field[] fields = c.getFields();
if (fields != null) {
String jsonStr = json;
if (propertyName != null) {
JSONObject jsonObject = new JSONObject(json);
jsonStr = jsonObject.get(propertyName).toString();
}
JSONArray jsonArray = new JSONArray(jsonStr);
objs = new ArrayList();
for (int i = 0; i < jsonArray.length(); i++) {
Object obj = c.newInstance();
objs.add(obj);
convertSingleObject(obj, jsonArray.getString(i));
}
}
} catch (Exception e) {
Log.d("convert", e.getMessage());
}
return objs;
}
/**
* 使用该方法需要先创建一个object,传入第一个参数 将JSON格式的数据转换为一个对象 json参数的值必须是一个JSON格式的对象,不能是数组
*
* @param obj
* @param json
* @return
*/
public static Object convertSingleObject(Object obj, String json) {
if (obj == null || json == null)
return obj;
try {
// 只使用public类型字段
Field[] fields = obj.getClass().getFields();
if (fields != null) {
JSONObject jsonObject = new JSONObject(json);
for (Field field : fields) {
try {
Object objValue = jsonObject.get(field.getName());
// 字符串类型
if (field.getType() == String.class) {
field.set(obj, String.valueOf(objValue));
}
// long类型
else if (field.getType() == long.class) {
field.set(obj,
Long.valueOf(String.valueOf(objValue)));
} // int类型
else if (field.getType() == int.class) {
field.set(obj,
Integer.valueOf(String.valueOf(objValue)));
}
// boolean类型
else if (field.getType() == boolean.class) {
field.set(obj, Boolean.getBoolean(String
.valueOf(objValue)));
}
// Object类型(WeiboObject类型)
else {
Object fieldObject = field.getType().newInstance();
if (fieldObject instanceof WeiboObject) {
convertSingleObject(fieldObject,
String.valueOf(objValue));
field.set(obj, fieldObject);
}
}
} catch (Exception e) {
}
}
}
} catch (Exception e) {
}
return obj;
}
}
到这里基本上把核心的代码贴完了,不过这里还有有一个类确实比较重要的, Utility这个类涉及到的都是Http通信,我们直接拿来用就可以的,不需要我们自己去写。要我说能完全自主开发出新浪微博客户端那确实很牛叉了,光是Http通信这一块,如果对http不熟悉,根本就不知道怎么来搞。
以上的代码并不是全部,但这些代码已经很有用了,对自己理解微博客户端的实现有了很大的启发。可能有些地方没能面面俱到,请见谅。下一篇博客可能会是关于发布一条微博的实现,敬请期待吧。