fanfou(饭否) android客户端 代码学习二
继续 代码学习1 因为重新编辑文章经常出现格式错乱,所以以后先写在记事本里面了 继续上次的发送消息 参考文献
appwidget简单入门和学习笔记 阻塞队列(BlockingQueue)
下一章:fanfou 如何定义httpException 取得图片部分
FanfouWidget.class
// 发送消息给widget
Intent reflogin = new Intent(this.getBaseContext(), FanfouWidget.class);
FanfouWidget.class继承自BroadcastReceiver..接收消息后执行onReceiver()方法
public void onReceive(Context context, Intent intent) {
if (!TwitterApplication.mApi.isLoggedIn()) {
//如果没有登录,将页面文本设置为请登录,替换其它文本为空
refreshView(context);
} else {
//已经登录
super.onReceive(context, intent);
String action = intent.getAction();
if (NEXTACTION.equals(action) || PREACTION.equals(action)) {
refreshView(context, intent.getAction());
} else if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
update(context);
}
}
}
//没有登录的操作
private void refreshView(Context context) {
//指明一个组件,参数为组件包名.类名
ComponentName fanfouWidget = new ComponentName(context,
FanfouWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
//将bulidLogin返回的RemoteViews类型的值所有appwidget的实例设置给定的组件fanfouWidget
manager.updateAppWidget(fanfouWidget, buildLogin(context));
}
//将原有标题替换为请登录,并删除其它的值
private RemoteViews buildLogin(Context context) {
RemoteViews updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget_initial_layout);
updateViews.setTextViewText(R.id.status_text,
TextHelper.getSimpleTweetText("请登录"));
updateViews.setTextViewText(R.id.status_screen_name, "");
updateViews.setTextViewText(R.id.tweet_source, "");
updateViews.setTextViewText(R.id.tweet_created_at, "");
return updateViews;
}
//已经登录
//根据userid去sqllite里面取出用户信息,然后显示到页面
//取出图片
/**
* 取图片, 可能直接从cache中返回, 或下载图片后返回
*/
public Bitmap get(String url, ImageLoaderCallback callback) {
Bitmap bitmap = ImageCache.mDefaultBitmap;
if (mImageManager.isContains(url)) {
bitmap = mImageManager.get(url);
} else {
// bitmap不存在,启动Task进行下载
mCallbackManager.put(url, callback);
startDownloadThread(url);
}
return bitmap;
}
public interface ImageCache {
public static Bitmap mDefaultBitmap = ImageManager
.drawableToBitmap(TwitterApplication.mContext.getResources()
.getDrawable(R.drawable.user_default_photo));
public Bitmap get(String url);
public void put(String url, Bitmap bitmap);
}
public class ImageManager implements ImageCache {
.....
//取出图片
//先将图片地址放入到List<>中,然后使用线程....
}
private void startDownloadThread(String url) {
if (url != null) {
//将图片地址存放到list中
addUrlToDownloadQueue(url);
}
// Start Thread
State state = mTask.getState();
//使用已有的线程
if (Thread.State.NEW == state) {
mTask.start(); // first start
} else if (Thread.State.TERMINATED == state) {
//如果线程为终止状态,则启动新的线程
mTask = new GetImageTask(); // restart
mTask.start();
}
}
...
@Override
public void run() {
try {
//private volatile boolean mTaskTerminated = false; 当执行完run方法后在finally里面设置为true;
while (!mTaskTerminated) {
String url;
//isPermanent默认为true ,提供了set方法,可以改变其值
if (isPermanent) {
//private BlockingQueue<String> mUrlList = new ArrayBlockingQueue<String>(50);
//Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是//Queue时,就完全只能访问Queue接口所定义的方法了,而不能直接访问LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。BlockingQueue 继承了Queue接口。
//队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就是说,队列以一种先进先出的方式管理数据,如果你试图向一个已经满了的//阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具。工作者线程可以定期地把中间结果存//到阻塞队列中而其他工作者线线程把中间结果取出并在将来修改它们。队列会自动平衡负载。如果第一个线程集运行得比第二个慢,则第二个线程集在等待结果时就会阻塞。如//果第一个线程集运行得快,那么它将等待第二个线程集赶上来。
//take 移除并返回队列头部的元素 如果队列为空,则阻塞
url = mUrlList.take();
} else {
//poll 移除并返回队列头部的元素 如果队列为空,则返回null
url = mUrlList.poll(TIMEOUT, TimeUnit.SECONDS); // waiting
if (null == url) {
break;
} // no more, shutdown
}
// Bitmap bitmap = ImageCache.mDefaultBitmap;
final Bitmap bitmap = mImageManager.safeGet(url);
// use handler to process callback
final Message m = handler.obtainMessage(HANDLER_MESSAGE_ID);
Bundle bundle = m.getData();
bundle.putString(EXTRA_IMAGE_URL, url);
bundle.putParcelable(EXTRA_BITMAP, bitmap);
handler.sendMessage(m);
}
} catch