当前位置:  编程技术>移动开发
本页文章导读:
    ▪OpenGL ES2学习札记(1)- OpenGL Console        OpenGL ES2学习笔记(1)-- OpenGL Console介绍 现在比较流行的编程语言基本上都自带了某种交互式工具,可以在里头直接输入代码,就地执行观察结果。比如Groovy提供的Groovy Shell和Groovy Console。 .........
    ▪ jquery Mobile点击展示加载等待效果        jquery Mobile点击显示加载等待效果 点击某个按钮或链接时,触发等待加载效果: 现在贴出一个小例子的完整代码,其中包含了各种等待加载效果, <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transiti.........
    ▪ 新浪微博客户端开发之受权登录+获取微博列表       新浪微博客户端开发之授权登录+获取微博列表新浪微博客户端开发之授权登录+获取微博列表 闲篇: 最近实在是乱得不行,至于怎么乱我也不知该怎么说,那么久没发博客就证明了这点,.........

[1]OpenGL ES2学习札记(1)- OpenGL Console
    来源: 互联网  发布时间: 2014-02-18
OpenGL ES2学习笔记(1)-- OpenGL Console
介绍

现在比较流行的编程语言基本上都自带了某种交互式工具,可以在里头直接输入代码,就地执行观察结果。比如Groovy提供的Groovy Shell和Groovy Console。

为了方便自己学习OpenGL ES2.0,快速试验各种API,我用Java Swing写了一个简单的应用:OpenGL Console。OpenGL Console和Groovy Console类似,在编辑器里输入Groovy脚本,调用各种OpenGL API,点击运行按钮便可立即看到效果:

用到的技术 Groovy 2.1.7

语法着色的Groovy代码编辑器使用了ConsoleTextEditor,执行Groovy脚本使用了GroovyShell。

JOGL 2.0.2

OpenGL库使用了JOGL2.0.2,JOGL为Java Swing应用提供了GLJPanel,用起来很简单,详情可以参考这个网页

Gradle

OpenGL Console用Gradle构建,对Gradle不太熟悉的可以看看我写的这篇文章

编译和运行OpenGL Console

安装Java7

安装Gradle

从github下载最新的OpenGL Console代码,解压到某个目录,比如D:\opengl-console-master

打开命令行,cd到OpenGL Console目录:

运行gradle installApp命令编译OpenGL Console代码并生成可执行文件:

进入opengl-console-master\build\install\glconsole\bin目录,双击glconsole.bat运行OpenGL Console:


OpenGL Console使用说明 右上角是Groovy脚本编辑器,在里头可以写Groovy脚本:

点击Run Script按钮运行脚本:


底部是输出窗口,可以看到脚本运行结果(点击Clear Output按钮可以清除输出):

右上角是绘图区域,可以拖动窗口改变这个区域的大小:





1楼jiangxigld昨天 18:35牛

    
[2] jquery Mobile点击展示加载等待效果
    来源: 互联网  发布时间: 2014-02-18
jquery Mobile点击显示加载等待效果

 点击某个按钮或链接时,触发等待加载效果:

现在贴出一个小例子的完整代码,其中包含了各种等待加载效果,


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css"
	href="/blog_article/css/jquery.mobile-1.3.2.min.css">
<script type="text/javascript" src="/blog_article/js/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="/blog_article/js/jquery.mobile-1.3.2.min.js"></script>
</head>
<script type="text/javascript">
	$(document).bind("mobileinit", function() {

	});
	$(function() {

		//默认设置,一个小圈圈在转

		$('#default').live('click', function() {
			//alert("ok");
			$.mobile.loadingMessageTextVisible = false;
			$.mobile.showPageLoadingMsg();
		});

		//小圈子外围加矩形的背景
		$('#loadingMessageTextVisible').live('click', function() {
			$.mobile.loadingMessageTextVisible = true;
			$.mobile.loadingMessageTheme = 'a';
			$.mobile.showPageLoadingMsg();
		});

		//矩形背景样式为e
		$('#loadingMessageTheme').live('click', function() {
			$.mobile.loadingMessageTextVisible = true;
			$.mobile.loadingMessageTheme = 'e';
			$.mobile.showPageLoadingMsg();
		});

		//小圈子下面加上文字
		$('#customText').live('click', function() {
			$.mobile.loadingMessageTextVisible = true;
			$.mobile.showPageLoadingMsg('a', "Please wait...");
		});

		//只有文字,没有小圈子在转
		$('#noSpinner').live('click', function() {
			$.mobile.loadingMessageTextVisible = true;
			$.mobile.showPageLoadingMsg('a', "Please wait...", true);
		});
	});
</script>
<body>
	<p>
		<a id="default" data-role="button">Default Loader</a>
	</p>
	<p>
		<a id="loadingMessageTextVisible" data-role="button">loadingMessageTextVisible
			= true</a>
	</p>

	<p>
		<a id="loadingMessageTheme" data-role="button">loadingMessageTheme
			= 'e'</a>
	</p>

	<p>
		<a id="customText" data-role="button">Custom Text</a>
	</p>

	<p>
		<a id="noSpinner" data-role="button">No Spinner</a>
	</p>
</body>
</html>



    
[3] 新浪微博客户端开发之受权登录+获取微博列表
    来源: 互联网  发布时间: 2014-02-18
新浪微博客户端开发之授权登录+获取微博列表
新浪微博客户端开发之授权登录+获取微博列表

闲篇:
最近实在是乱得不行,至于怎么乱我也不知该怎么说,那么久没发博客就证明了这点,一般如果小巫有做详尽的计划,并把时间投入到上面的话,我是可以用最短的时间里把新浪微博客户端给整出来的,但现在进度很慢,我越来越不像个称职的程序猿,因为现在的生活已经不再是代码,更多的是想多享受跟朋友们在一起的快乐。这些话也不多说了,关于这个项目,其实我也头痛了一整子,我很久之前就买了一本李宁的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(/blog_article/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(/blog_article/String mRedirectUrl/index.html) {
        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(/blog_article/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(/blog_article/parameters/index.html);
        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(/blog_article/Activity activity, String url/index.html) {
		return getImageurl(/blog_article/activity, url, null/index.html);
	}

	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(/blog_article/url/index.html);
				} 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不熟悉,根本就不知道怎么来搞。


以上的代码并不是全部,但这些代码已经很有用了,对自己理解微博客户端的实现有了很大的启发。可能有些地方没能面面俱到,请见谅。下一篇博客可能会是关于发布一条微博的实现,敬请期待吧。




    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3