8.4. 从 Twitter 读取数据

优质
小牛编辑
132浏览
2023-12-01

8.4.从 Twitter 读取数据

我们已经有了个大体的框架,接下来就连接到 Twitter ,读取数据并且在程序中显示出来。Twitter 或者其他的微博平台提供的 API 都各不相同。这时可以使用三方库jtwitter.jar,它提供了一个Twitter类作为封装。里边最常用的功能之一就是getFriendsTimeline(),它可以返回24小时中自己和朋友的最新20条消息。

要使用 Twitter API 的这一特性,首先应连接到 Twitter 服务。我们需要一个用户名、密码,以及一个API授权。回忆下本章前面 “Yamba 的 Application 对象” 一节中,我们已经把大部分相关的功能重构到了 YambaApplication 中。因此我们得以在这里重用这一功能,因为包括 Service 在内的程序中任何一个构件,都可以访问同一个 Application 对象。

在这里我们需要小小地修改下 YambaAppliaction ,好让别人知道这个 Service 是否正在运行。因此在 YambaApplication 中添加一个标志变量,配合 getter 与 setter 用以访问与更新:

public class YambaApplication extends Application implements OnSharedPreferenceChangeListener {

private boolean serviceRunning; //

...

public boolean isServiceRunning() { //

return serviceRunning;

}

public void setServiceRunning(boolean serviceRunning) { //

this.serviceRunning = serviceRunning;

}

}

  1. 这个标志变量表示了 Service 的运行状态。注意它是个私有成员,不可以直接访问。
  2. 这个全局方法用以访问标志变量serviceRunning的值。
  3. 另一个全局方法,用以设置标志变量serviceRunning的值。

接下来我们可以为UpdaterService写些代码,让它连接到API,读取朋友的最新消息。

例 8.6. UpdaterService.java, final version

package com.marakana.yamba3;

import java.util.List;

import winterwell.jtwitter.Twitter;

import winterwell.jtwitter.TwitterException;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.util.Log;

public class UpdaterService extends Service {

private static final String TAG = "UpdaterService";

static final int DELAY = 60000; // wait a minute

private boolean runFlag = false;

private Updater updater;

private YambaApplication yamba; //

@Override

public IBinder onBind(Intent intent) {

return null;

}

@Override

public void onCreate() {

super.onCreate();

this.yamba = (YambaApplication) getApplication(); //

this.updater = new Updater();

Log.d(TAG, "onCreated");

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

super.onStartCommand(intent, flags, startId);

this.runFlag = true;

this.updater.start();

this.yamba.setServiceRunning(true); //

Log.d(TAG, "onStarted");

return START_STICKY;

}

@Override

public void onDestroy() {

super.onDestroy();

this.runFlag = false;

this.updater.interrupt();

this.updater = null;

this.yamba.setServiceRunning(false); //

Log.d(TAG, "onDestroyed");

}

/**

* Thread that performs the actual update from the online service

*/

private class Updater extends Thread {

List<Twitter.Status> timeline; //

public Updater() {

super("UpdaterService-Updater");

}

@Override

public void run() {

UpdaterService updaterService = UpdaterService.this;

while (updaterService.runFlag) {

Log.d(TAG, "Updater running");

try {

// Get the timeline from the cloud

try {

timeline = yamba.getTwitter().getFriendsTimeline(); //

} catch (TwitterException e) {

Log.e(TAG, "Failed to connect to twitter service", e); //

}

// Loop over the timeline and print it out

for (Twitter.Status status : timeline) { //

Log.d(TAG, String.format("%s: %s", status.user.name, status.text)); //

}

Log.d(TAG, "Updater ran");

Thread.sleep(DELAY);

} catch (InterruptedException e) {

updaterService.runFlag = false;

}

}

}

} // Updater

}

  1. 这个变量用以方便访问YambaApplication对象,便于使用其中的共享功能,比如读取用户设置、连接到远程服务等。
  2. 通过getApplication()方法获得YambaApplication对象的引用。
  3. 一旦启动了这个 Service ,我们就设置YambaApplication中的标志变量serviceRunning。
  4. 同样,等 Service 停止时也修改YambaApplication对象中的serviceRunning。
  5. 我们使用了 Java 中的泛型来定义一个存放Twitter.Status的 List 变量。
  6. 调用YambaApplication中的getTwitter()方法获得 Twitter 对象,然后调用getFriendTimeline()来获得24小时内朋友最新的20条消息。注意因为这个函数需要访问云端服务,所以其运行时间受网络延迟影响比较大。我们把它安置在一个独立的线程中,从而防止它拖慢用户界面的响应。
  7. 网络相关的操作失败的原因有很多。我们在这里捕获异常,并打印出错时的堆栈信息。其输出在 Logcat 中可见。
  8. 现在我们已经初始化了 timeline这个 List ,可以遍历其中的元素。最简单的方法就是使用 Java 的 "foreach" 循环,自动地遍历我们的 List ,分别把每个元素的引用交给变量 status。
  9. 暂时我们先把消息也就是“谁说了什么“输出到 Logcat。