在Android中显示Twitter状态






4.92/5 (12投票s)
Twitter状态进入移动端
引言
Twitter 是一个非常流行的内容分享和社交网络平台。在本文中,我们将探讨如何在 Android 应用程序中显示 Twitter 状态(称为推文)。
Twitter API
Twitter 提供 API,开发人员可以使用它来构建围绕 Twitter 功能的应用程序。它拥有良好的文档和许多代码示例可供尝试。在本文中,我们仅使用 Twitter 状态功能。有关 Twitter API 功能的完整列表,请参阅 Twitter API 文档。
假设用户的每条推文都是公开的,除非用户将其设为私有。这意味着,如果其他人知道您的用户账户,他们就可以看到您的推文。但是,您的应用程序是 Twitter API 环境的访客,因此应该与 Twitter 环境和谐共处。例如,您的应用程序每小时只能进行 150 次 REST 请求,每天最多更新 1000 条状态。有关完整的条款和条件,请参阅 Twitter 文档。
Twitter API 使用 REST(Representational State Transfer)风格,因此任何请求都以 HTTP 请求的形式发送,例如 GET 或 POST,就像浏览网页一样。
获取用户状态更新
Twitter API 以 JSON 或 XML 的形式呈现推文。例如,要以 JSON 格式获取用户名 zpjuhara(我的个人 Twitter 账户)的公共状态:
https://api.twitter.com/1/statuses/user_timeline/zpjuhara.json
{"errors":[{"message":"The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview.","code":64}]}
Android 中的 HTTP 库
Android 提供了两种风格的 HTTP 库:HTTPClient (org.apache.http.client.HttpClient) 和 HttpURLConnection (java.net.HttpURLConnection) 或 HttpsURLConnection (javax.net.ssl.HttpsURLConnection) 用于 HTTPS 协议。
第一种仍受支持。但是,Android SDK 开发人员表示,他们的开发工作重点放在 HttpURLConnection/HttpsURLConnection 上。在本文中,我们使用 HttpsURLConnection。
权限
为了能够访问 Internet 并使用 Android 中的网络 API,应用程序必须在AndroidManifest.xml中请求`android.permission.INTERNET`权限。
<uses-permission android:name = "android.permission.INTERNET"/>
使用 HttpsURLConnection 通过网络读取数据
HttpsURLConnection
派生自HttpURLConnection
,并间接派生自 URLConnection。要获取HttpsURLConnection
实例,您需要执行以下操作:
- 创建 URL 实例。
- 调用 URL 的 openConnection() 方法以获取
URLConnection
实例。 - 将
URLConnection
实例类型转换为HttpsURLConnection
。请确保您实际使用的是 HTTPS 协议(在 URL 中使用 https://)。 - 初始化
HttpsURLConnection
并调用 connect() 来开始打开连接。 - 使用 getInputStream() 读取数据,或使用 getOutputStream() 写入数据。如果您尚未调用,这两种方法都会隐式调用 connect()。
private HttpsURLConnection openHttps(String a_url) throws IOException
{
URL url = new URL(a_url);
HttpsURLConnection httpsconn=(HttpsURLConnection) url.openConnection();
return httpsconn;
}
private HttpsURLConnection download(String screen_name) throws IOException
{
return openHttps(
"https://api.twitter.com/1/statuses/"+
"user_timeline/"+screen_name+".json");
}
要开始从HttpsURLConnection
读取数据,请调用getInputStream()
并对该方法返回的InputStream
实例执行 I/O 操作。
private String readStream(InputStream ins) throws IOException
{
InputStreamReader isr = new InputStreamReader(ins);
int charRead;
StringBuilder str = new StringBuilder();
char[] inputBuffer = new char[1024];
while ((charRead = isr.read(inputBuffer,0, 1024))>0)
{
str.append(String.copyValueOf(
inputBuffer, 0, charRead));
}
ins.close();
return str.toString();
}
将 I/O 操作移出 UI 线程
I/O 操作通常是阻塞操作。它们通常非常慢,会阻塞线程执行直到完成。Android 应用程序有一个称为 UI 线程的主线程,GUI 更新和输入交互在该线程上进行。如果您的应用程序在 UI 线程中执行大量操作,它就会阻塞 UI 线程。当 UI 线程执行被阻塞时,应用程序无法更新屏幕,也无法接收用户的输入。从用户的角度来看,应用程序似乎卡住了。这不好。
Android 对应用程序冻结的时间长度有限制(通常约为 5 秒)。如果您的应用程序在 5 秒内无法完成计算,它将被视为冻结,Android 将显示“应用程序无响应”(ANR) 对话框,告知用户是否希望等待应用程序完成或将其关闭。确保将耗时的 I/O 操作(如从网络读取数据)移出 UI 线程非常重要。
幸运的是,Android 使我们的生活变得更轻松。有很多方法可以解决这个问题。您可以使用 Thread、Handler 或 AsyncTask。对于执行短期耗时 I/O 操作(如从网络读取数据),使用 AsyncTask 来解决此问题更为合适。要使用 AsyncTask,您必须将其子类化并实现其抽象方法 doInBackground()。这就是您放置耗时操作的地方。它在 UI 线程之外运行,因此您必须确保始终同步对两个线程共享的资源的访问。如果可以完全隔离它们,则无需共享资源,这样更好。
您还可以选择覆盖 onPreExecute() 和 onPostExecute(),它们分别在doInBackground()
之前和之后执行。这两个方法都将在 UI 线程内部执行,因此调用影响 GUI 元素的任何方法都是安全的。
private class TwitterStatusesTask extends AsyncTask<String,Void,Void>
{
public ArrayList<twitterstatuses.status> statuses=null;
@Override
protected void onPostExecute(Void result)
{
//onPostExecute executed in UI thread
StatusAdapter statAdapt=new StatusAdapter();
statAdapt.statuses=statuses;
ListView lstvw=(ListView)findViewById(R.id.listView1);
lstvw.setAdapter(statAdapt);
super.onPostExecute(result);
}
@Override
protected Void doInBackground(String... screen_name)
{
TwitterStatuses twtr=new TwitterStatuses();
statuses=twtr.get(screen_name[0]);
return null;
}
}
读取 JSON 数据
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于网络通信。JSON 的优点在于其紧凑的结构,所需的存储空间少,并且易于解析,因为 JSON 本质上是 JavaScript 代码中的对象表示。
Android SDK 提供处理 JSON 的库,因此 Android 开发人员可以轻松读取 JSON 数据。JSON 数据的示例如下:
{"ids":[{"id":"12345"},{"id":"67890"}]}
JSON 数据使用 {} 和 []。它们有什么区别?{} 结构用于表示对象(JSONObject),而 [] 用于定义数组(JSONArray)。要读取上面的 JSON 数据:
JSONObject jsonObj=new JSONObject(
"{\"ids\":[{\"id\":\"12345\"},"+
"{\"id\":\"67890\"}]}");
JSONArray ids=
jsonObj.getJSONArray("ids");
JSONObject id0=ids.getJSONObject(0);
JSONObject id1=ids.getJSONObject(1);
//id00=12345
int id00=id0.getInt("id");
//id01=67890
int id01=id1.getInt("id");
显示 I/O 进度指示
网络 I/O 操作需要时间。显示一个视觉指示表明正在进行操作是一种良好的实践。对于网络 I/O 操作,有时我们不知道需要多长时间。为了显示用户操作已被处理但尚未完成的视觉指示,应用程序可以在 AsyncTask 的onPreExecute()
中显示等待动画,并在onPostExecute()
中隐藏它。
如果操作的时长已知,您可以在doInBackground()
中调用 publishProgress() 来指示操作进度。然后实现 onProgressUpdate() 来使视觉指示可见。
@Override
protected void onPreExecute()
{
//show progress bar
ProgressBar progress=(ProgressBar)findViewById(R.id.progressBar1);
progress.setVisibility(View.VISIBLE);
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result)
{
//do something
//hide progress bar
ProgressBar progress=(ProgressBar)findViewById(R.id.progressBar1);
progress.setVisibility(View.INVISIBLE);
super.onPostExecute(result);
}
使用代码
要使用源代码,只需将源代码复制到 Eclipse IDE 工作区。添加新项目并将其指向现有代码。