1. 程式人生 > >Android 項目開發基礎再回顧(一)

Android 項目開發基礎再回顧(一)

android

1,主activity_splash:

<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:background="@drawable/launcher_bg"//設置初始背景圖片

tools:context=".SplashActivity" >


<TextView

android:id="@+id/tv_version_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerInParent="true"#把這個textview 放到中間

android:shadowDx="1//這個指的是相對於原字體在x方向上的偏移量

android:shadowDy="1"

android:shadowColor="#f00"//黑色

android:shadowRadius="1"//表示陰影的模糊程度

android:textSize="16sp"

android:text="版本名稱" />

<ProgressBar //加載滾動條

android:layout_below="@id/tv_version_name"

android:layout_centerHorizontal="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>


</RelativeLayout>

2,副activity_home

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

<TextView

android:text="HomeActivity"

android:textSize="20sp"

android:textColor="#000"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>


</LinearLayout>

3,讓第二個活動可以啟動

<activity

android:name="com.example.moblesafe73.HomeActivity"/>

4,接下來創造兩個工具類,

一個是將流轉化為字符串

mport java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;


public class StreamUtil {


public static String StreamToString(InputStream is) {

//1.在讀取的過程中,將讀取的內容存取到緩存中,然後一次性用字符轉化成字符串

ByteArrayOutputStream bos=new ByteArrayOutputStream();

//2.讀取操作,讀到沒有為止(循環)

byte[] buffer=new byte[1024];

//3.記錄讀取內容的臨時變量

int temp=-1;

try {

while((temp=is.read(buffer))!=-1){

bos.write(buffer,0,temp);

}

//返回讀取的數據

return bos.toString();

} catch (IOException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

}finally{

try {

is.close();

bos.close();

} catch (IOException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

}

}

return null;

}


}

另一個是可以彈出toast

import android.content.Context;

import android.widget.Toast;


public class ToastUtils {

public static void show(Context ctx,String msg){

Toast.makeText(ctx, msg, 0).show();

}


}

5,主營業務的介紹:

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//去除當前activity頭title

requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.activity_splash);

//初始化ui

initUI();

//初始化方法

initData();

}

6,關於如何初始化ui

private void initUI() {

// TODO 自動生成的方法存根

tv_version_name = (TextView) findViewById(R.id.tv_version_name);

}


找到相應控件

private void initData() {

// TODO 自動生成的方法存根

//應用版本名稱

tv_version_name.setText(getVersionName());

//獲取本地服務版本號

myLockVersionCode = getVersionCode();

//獲取服務器版本號(客戶端發請求,服務器給相應(json,xml一般用的是json))

checkVersion();

}

//返回版本號

private int getVersionCode() {

// TODO 自動生成的方法存根

//1,包管理者對象packagemanager

PackageManager pm=getPackageManager();

//2,從包的管理者對象中,獲取指定包名的基本信息(版本名稱,版本號,0代表基本信息)

try {

PackageInfo packageinfo=pm.getPackageInfo(getPackageName(), 0);

return packageinfo.versionCode;

} catch (NameNotFoundException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

}

return 0;

}

這個方法可以

技術分享圖片

再來看checkVersion();方法

如果上網的話需要用到線程方面的知識

private void checkVersion() {

new Thread(){



public void run(){

//Message message=new Message();

Message msg=Message.obtain();

long startTime=System.currentTimeMillis();//程序開始的時間

try {

//封裝url地址

URL url=new URL("http://192.168.1.104:8080/update74.json");

//開啟一個地址

HttpURLConnection connection=(HttpURLConnection)url.openConnection();

//3,設置常見的請求參數(請求頭)

//請求超時

connection.setConnectTimeout(2000);

//讀取超時

connection.setReadTimeout(2000);

//默認是get請求

//connection.setRequestMethod("POST");

//獲取請求響應碼

if(connection.getResponseCode()==200){

//5.以流的形式,將數據保存起來

InputStream is=connection.getInputStream();

//6.將流換成字符串(工具類封裝)

String json=StreamUtil.StreamToString(is);

Log.i(tag, json);//打印日誌

//7.json解析

JSONObject jsonObject=new JSONObject(json);

String versionName=jsonObject.getString("versionName");

mversionDes = jsonObject.getString("versionDes");

String versionCode=jsonObject.getString("versionCode");

mdownloadUrl = jsonObject.getString("downloadUrl");

Log.i(tag, versionName);

Log.i(tag, mversionDes);

Log.i(tag, versionCode);

Log.i(tag, mdownloadUrl);

//8,比對版本號(服務器版本號,提示用戶更新)

if(myLockVersionCode <Integer.parseInt(versionCode)){

//提示用戶更新,彈出對話框

msg.what=UPDATE_VERSION;

}else{

//進入應用程序主界面

msg.what=ENTER_HOME;

}

}

}catch (MalformedURLException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

msg.what=URL_ERROR;

}catch (IOException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

msg.what=IO_ERROR;

} catch (JSONException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

msg.what=JSON_ERROR;

}finally{

//請求網絡的時長超過四秒則不做處理

//請求小於四秒,強制讓其睡眠四秒

long endTime=System.currentTimeMillis();

if(endTime-startTime<4000)

{

try {

Thread.sleep(4000-(endTime-startTime));

} catch (InterruptedException e) {

// TODO 自動生成的 catch 塊

e.printStackTrace();

}

}

mhandler.sendMessage(msg);

}

};

}.start();

對上述信息進行相關的處理:

private Handler mhandler=new Handler(){

public void handleMessage(android.os.Message msg){

switch(msg.what){

case UPDATE_VERSION:

//彈出對話框,提示用戶更新

showUpdateDialog();//彈出一個對話框,讓我們進行更新

break;

case ENTER_HOME:

enterHome();

break;

case IO_ERROR:

ToastUtils.show(getApplicationContext(), "IO異常");

enterHome();

break;

case URL_ERROR:

ToastUtils.show(getApplicationContext(), "url異常");

enterHome();

break;

case JSON_ERROR:

ToastUtils.show(getApplicationContext(), "URL異常");//SplashActivity.this

enterHome();

break;

}

}


};

protected void showUpdateDialog() {

// TODO 自動生成的方法存根

//對話框是依賴activity存在的

Builder builder = new AlertDialog.Builder(this);//必須用this,而不是getApplicationContext()

builder.setIcon(R.drawable.ic_launcher);

builder.setTitle("版本更新");

//設置描述內容

builder.setMessage(mversionDes);//這個描述內容見上文是由其發送過來的

//積極按鈕,立即更新

builder.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

//下載apk,apk鏈接地址,downloadUrl

downloadApk();

}

});//創建兩個按鈕監聽器

builder.setNegativeButton("稍後再說", new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

//取消對話框,進入主界面

enterHome();

}

});

builder.show();

}

接下來是對文件進行下載

protected void downloadApk() {

//apk下載鏈接地址,放置apk的所在路徑

//1,判斷sd卡是否可用,是否掛在上

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

//2,獲取sd卡路徑

String path=Environment.getExternalStorageDirectory().getAbsolutePath()

+File.separator+"mobilesafe73.apk";

//發送請求,獲取sdk,並且添加到指定路徑

HttpUtils httpUtils=new HttpUtils();

//發送請求,傳遞參數吧(下載應用放置的位置)

httpUtils.download(mdownloadUrl, path,new RequestCallBack<File>() {//mdownloadUrl剛才所獲得的下載的地址

@Override

public void onSuccess(ResponseInfo<File> responseInfo) {

Log.i(tag, "下載成功");

// TODO 自動生成的方法存根

File file=responseInfo.result;

//提示用戶安裝

installAPK(file);

}

@Override

public void onFailure(HttpException arg0, String arg1) {

Log.i(tag, "下載失敗");

// TODO 自動生成的方法存根

}

@Override

public void onStart() {

// TODO 自動生成的方法存根

Log.i(tag, "開始下載");

super.onStart();

}

@Override

public void onLoading(long total, long current, boolean isUploading) {

// TODO 自動生成的方法存根

Log.i(tag, "下載中........");

Log.i(tag, "total = "+total);

Log.i(tag, "current = "+current);

super.onLoading(total, current, isUploading);

}

});

}

}

//開始安裝

protected void installAPK(File file) {

// TODO 自動生成的方法存根

//系統應用界面,源碼,安裝apk入口

Intent intent = new Intent("android.intent.action.VIEW");

intent.addCategory("android.intent.category.DEFAULT");

/*//文件作為數據源

intent.setData(Uri.fromFile(file));

//設置安裝的類型

intent.setType("application/vnd.android.package-archive");*/

intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");

// startActivity(intent);

startActivityForResult(intent, 0);

}

//開啟另一個界面

protected void enterHome() {

Intent intent = new Intent(this,HomeActivity.class);

startActivity(intent);

//在開啟一個新的界面後將導航界面關閉,因為導航界面只可見一次

finish();

}


Android 項目開發基礎再回顧(一)