65.9K
CodeProject 正在变化。 阅读更多。
Home

在Android中显示Twitter状态

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (12投票s)

2013年4月16日

CPOL

5分钟阅读

viewsIcon

37015

downloadIcon

1070

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
更新(2015 年 7 月 9 日):Twitter REST API 版本 1.0 已不再可用,因此上述 URL 将不再起作用,您将收到如下 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}]}
您需要通过将 URL 中的1替换为1.1来迁移到版本 1.1。自 API v1.1 起,您需要使用 OAuth 来验证您的请求。

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 使我们的生活变得更轻松。有很多方法可以解决这个问题。您可以使用 ThreadHandlerAsyncTask。对于执行短期耗时 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 工作区。添加新项目并将其指向现有代码。

© . All rights reserved.