使用雲(BAE)實現android應用數據的遠程存取(MySQL)

文章來源:http://xevan.net/bae-for-android/

在做android應用的時候,我們不可避免的要存取數據,而且更多的時候用的就是本地的MySQL服務器,但是通過百度的BAE卻能實現數據的遠程存取,即在公網內訪問。本文就簡單的通過一個實例來向大家說明怎樣使用BAE來使用雲數據庫。

1、什麼是BAE?

百度雲環境,即BAE(百度應用引擎),提供多語言、彈性的服務端運行環境,能幫助開發者快速開發並部署應用。雲環境內置豐富的分佈式計算API,並支持全方位的百度“雲”服務,更能爲您的應用帶來強大動力,從“本地”變“分佈式”,簡單可依賴。具體可參見上面的官網鏈接。

我們這裏用到的就是百度的雲存儲。

2、部署雲環境

註冊百度帳號,點擊管理中心,填寫相關的個人信息。並激活郵箱。

點擊創建應用,選擇web應用,填寫應用名稱,並選擇PC Iframe

選擇雲環境,進行手機驗證,然後進行託管設置,域名隨意選取,並選擇環境類型爲java,確定,提示創建應用成功。

回到基本信息處,此時應用已經有了AppID(BAE託管)

點擊雲環境---->雲數據庫---->創建數據庫,當然是用免費的了。

此時雲環境部署成功,

3、向雲端數據庫寫入測試數據。

點擊操作欄下的phpmyadmin(這是用php寫成的用於管理mysql數據庫的可視化應用程序)(注:safari瀏覽器無法打開,如果你不能打開的時候嘗試換用其它瀏覽器)

打開界面如下

新建一張表,名字隨意填寫,這裏爲evanTest,字段數是指有幾個變量,這裏填寫3個吧。並點擊執行,填寫變量名字和類型和長度,點擊保存

點擊數據表後邊的插入選項,我們寫入一組數據吧,並點擊執行

至此,數據表裏就多了一組數據。

4、搭建本地WEB應用並部署至BAE雲端

點擊這裏安裝插件,或者直接點擊這裏(一鍵安裝)下載集成的開發環境。

首先我們在安裝好插件或者下載好的eclipse上能看到百度的標誌,點擊並選擇New BAE Project(Java)

我的項目取名爲evan,新建後我們發現跟一般的web服務器基本是一致的,而且還給我們省去了很多搭建各種環境的步驟,很是方便!

我們直接修改HelloWorldServlet.java的代碼(這個類其實就是Servlet),在這裏邊處理android客戶端的請求。

文件代碼如下:

package test;

import java.io.DataOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baidu.bae.api.util.BaeEnv;

public class HelloWorldServlet extends HttpServlet {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		String host = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_ADDR_SQL_IP);
		String port = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_ADDR_SQL_PORT);
		String username = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_AK);
		String password = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_SK);
		String driverName = "com.mysql.jdbc.Driver";
		String dbUrl = "jdbc:mysql://";
		String serverName = host + ":" + port + "/";
		// 從平臺查詢應用要使用的數據庫名
		String databaseName = "HDxhGItkNqwdecJzXubX";
		String connName = dbUrl + serverName + databaseName;
		String sql = "select * from evanTest";
		String info;
		Connection connection = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			Class.forName(driverName);
			// 具體的數據庫操作邏輯
			connection = DriverManager.getConnection(connName, username,
					password);
			stmt = connection.createStatement();
			rs = stmt.executeQuery(sql);
			String m_name = "", m_school = "", m_city = "";
			DataOutputStream output = new DataOutputStream(resp.getOutputStream() );
			while (rs.next()) {
				m_name = rs.getString("name");
				m_school = rs.getString("school");
				m_city = rs.getString("city");
				resp.setContentType("text/plain");
				info = m_name + "_" + m_school + "_" + m_city;
				output.writeUTF(info);
			}
			output.close();
		} catch (ClassNotFoundException ex) {
			// 異常處理邏輯
		} catch (SQLException e) {
			// 異常處理邏輯

		} finally {
			try {
				if (connection != null) {
					connection.close();
				}
			} catch (SQLException e) {

			}
		}
	}
}

 

將第36行改爲自己數據庫的名字,數據庫的名字在創建數據庫的時候已經給了。

將第38行from後面改爲自己表的名字。

點擊百度標誌---->Deploy To BAE,點擊Project Properties

填寫下面的表,ApplicationID就是之前我們進行手機驗證之後的AppID(BAE託管),Access Key(就是API Key)和Secure Key在百度我們的應用頁面也很容易找到

填寫完畢後點OK,再點擊Deploy,輸入自己的帳號密碼,部署成功後會顯示,隨便選擇就可以。

在瀏覽器輸入我們最開始填入的域名,我填的是zyfevan.duapp.com,在瀏覽器輸入1.zyfevan.duapp.com,會顯示

說明成功了,這個頁面就是我們剛纔的項目裏的index.jsp顯示的,若輸入1.zyfevan.duapp.com/hello同樣會得到數據庫裏邊的數據,Servlet的定義是在項目WEB-INF的web.xml裏定義的

至此服務器搭建完畢。

5、在android客戶端獲取服務器的數據

新建一個android項目,首先我們佈局一下界面,activity_main.xml的代碼如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/m_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/m_textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="22dp"
        android:text="從數據庫獲取東西" />

    <TextView
        android:id="@+id/m_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="62dp"
        android:text="這是原始的東西" />

</RelativeLayout>

 

然後再改寫主文件,MainActivity.java的代碼如下:

package com.example.testtaxi;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.StringTokenizer;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	private Button m_button;
	private TextView m_textView;
	private String url = "http://1.zyfevan.duapp.com/hello";
	private StringTokenizer info;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		m_button = (Button) findViewById(R.id.m_button);
		m_textView = (TextView) findViewById(R.id.m_textView);
		m_button.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				new Thread(new Runnable() {
					public void run() {
						try {
							HttpGet httpRequest = new HttpGet(url);
							HttpResponse httpResponse = new DefaultHttpClient()
									.execute(httpRequest);
							// 判斷請求是否成功
							if (httpResponse.getStatusLine().getStatusCode() == 200) {
								HttpEntity entity = httpResponse.getEntity();
								if (entity != null) {
									info = new StringTokenizer(EntityUtils
											.toString(entity, "utf-8"), "_");
									if (info.countTokens() % 3 != 0) {
										Log.v("error", "不夠3段");
									}
									m_textView.post(new Runnable() {
										public void run() {
											m_textView.setText(
													"name:"
													+ info.nextToken()
													+ " school:"
													+ info.nextToken()
													+ " city:"
													+ info.nextToken());
										}
									});
								}
							}
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}).start();
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

 

其中第33行爲我們Servlet的鏈接

49---60行爲通過網絡獲取數據的代碼


 

需要特別說明的兩點是:

  • 從android4.0開始就不允許在主線程裏訪問網絡,所以在第46行我們在線程中訪問網絡
  • 對View的操作不能再線程中進行,所以第61行我們使用了官網介紹的post方法,用Runnable來修改TextView的內容

 

運行效果,剛打開程序:

點擊按鈕後:

說明我們能從雲端數據庫獲取數據了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章