編輯:關於android開發
開源中國android端版本號:2.4
在AndroidManifest.xml中找到程序的入口,
<activityandroid:name=".AppStart"android:label="@string/app_name"android:screenOrientation="portrait"android:theme="@style/Theme.AppStartLoad" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
屏幕方向設置為豎屏,主題為AppStartLoad,關於它的定義如下:
<style name="Theme.AppStartLoad" parent="android:Theme.Black.NoTitleBar.Fullscreen"><item name="android:windowBackground">@drawable/welcome</item><item name="android:windowNoTitle">true</item></style>
welcome.png就是啟動頁顯示的圖片,填充了整個屏幕。
AppStart.java文件:
package net.oschina.app;import java.io.File;import net.oschina.app.ui.MainActivity;import net.oschina.app.util.TDevice;import org.kymjs.kjframe.http.KJAsyncTask;import org.kymjs.kjframe.utils.FileUtils;import org.kymjs.kjframe.utils.PreferenceHelper;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;/*** 應用啟動界面** @author FireAnt(http://my.oschina.net/LittleDY)* @created 2014年12月22日 上午11:51:56**/public class AppStart extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 防止第三方跳轉時出現雙實例Activity aty = AppManager.getActivity(MainActivity.class);if (aty != null && !aty.isFinishing()) {finish();}// SystemTool.gc(this); //針對性能好的手機使用,加快應用相應速度final View view = View.inflate(this, R.layout.app_start, null);setContentView(view);// 漸變展示啟動屏AlphaAnimation aa = new AlphaAnimation(0.5f, 1.0f);aa.setDuration(800);view.startAnimation(aa);aa.setAnimationListener(new AnimationListener() {@Overridepublic void onAnimationEnd(Animation arg0) {redirectTo();}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationStart(Animation animation) {}});}@Overrideprotected void onResume() {super.onResume();int cacheVersion = PreferenceHelper.readInt(this, "first_install","first_install", -1);int currentVersion = TDevice.getVersionCode();if (cacheVersion < currentVersion) {PreferenceHelper.write(this, "first_install", "first_install",currentVersion);cleanImageCache();}}private void cleanImageCache() {final File folder = FileUtils.getSaveFolder("OSChina/imagecache");KJAsyncTask.execute(new Runnable() {@Overridepublic void run() {for (File file : folder.listFiles()) {file.delete();}}});}/*** 跳轉到...*/private void redirectTo() {Intent uploadLog = new Intent(this, LogUploadService.class);startService(uploadLog);Intent intent = new Intent(this, MainActivity.class);startActivity(intent);finish();}}
AppManager.java文件:
package net.oschina.app;import java.util.Stack;import android.app.Activity;import android.content.Context;/*** activity堆棧式管理** @author FireAnt(http://my.oschina.net/LittleDY)* @created 2014年10月30日 下午6:22:05**/public class AppManager {private static Stack<Activity> activityStack;private static AppManager instance;private AppManager() {}/*** 單一實例*/public static AppManager getAppManager() {if (instance == null) {instance = new AppManager();}return instance;}/*** 添加Activity到堆棧*/public void addActivity(Activity activity) {if (activityStack == null) {activityStack = new Stack<Activity>();}activityStack.add(activity);}/*** 獲取當前Activity(堆棧中最後一個壓入的)*/public Activity currentActivity() {Activity activity = activityStack.lastElement();return activity;}/*** 結束當前Activity(堆棧中最後一個壓入的)*/public void finishActivity() {Activity activity = activityStack.lastElement();finishActivity(activity);}/*** 結束指定的Activity*/public void finishActivity(Activity activity) {if (activity != null && !activity.isFinishing()) {activityStack.remove(activity);activity.finish();activity = null;}}/*** 結束指定類名的Activity*/public void finishActivity(Class<?> cls) {for (Activity activity : activityStack) {if (activity.getClass().equals(cls)) {finishActivity(activity);break;}}}/*** 結束所有Activity*/public void finishAllActivity() {for (int i = 0, size = activityStack.size(); i < size; i++) {if (null != activityStack.get(i)) {//finishActivity方法中的activity.isFinishing()方法會導致某些activity無法銷毀//貌似跳轉的時候最後一個activity 是finishing狀態,所以沒有執行//內部實現不是很清楚,但是實測結果如此,使用下面代碼則沒有問題// find by TopJohn//finishActivity(activityStack.get(i));activityStack.get(i).finish();//break;}}activityStack.clear();}/*** 獲取指定的Activity** @author kymjs*/public static Activity getActivity(Class<?> cls) {if (activityStack != null)for (Activity activity : activityStack) {if (activity.getClass().equals(cls)) {return activity;}}return null;}/*** 退出應用程序*/public void AppExit(Context context) {try {finishAllActivity();// 殺死該應用進程android.os.Process.killProcess(android.os.Process.myPid());System.exit(0);} catch (Exception e) {}}}
在上面onResume方法中,(這裡單獨拿出來),邏輯是更新版本號,查看當前安裝的apk的版本號,與shared_prefs目錄下first_install.xml文件中key為“first_install”對應的value的值的關系。
@Overrideprotected void onResume() {super.onResume();int cacheVersion = PreferenceHelper.readInt(this, "first_install","first_install", -1);int currentVersion = TDevice.getVersionCode();if (cacheVersion < currentVersion) {PreferenceHelper.write(this, "first_install", "first_install",currentVersion);cleanImageCache();}}
first_install.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?><map><int name="first_install" value="48" /></map>
TDevice文件下的getVersionCode()方法:
public static int getVersionCode() {int versionCode = 0;try {versionCode = BaseApplication.context().getPackageManager().getPackageInfo(BaseApplication.context().getPackageName(),0).versionCode;} catch (PackageManager.NameNotFoundException ex) {versionCode = 0;}return versionCode;}
刪除圖像緩存:
private void cleanImageCache() {final File folder = FileUtils.getSaveFolder("OSChina/imagecache");KJAsyncTask.execute(new Runnable() {@Overridepublic void run() {for (File file : folder.listFiles()) {file.delete();}}});}
getSaveFolder方法:
/*** 獲取文件夾對象** @return 返回SD卡下的指定文件夾對象,若文件夾不存在則創建*/public static File getSaveFolder(String folderName) {File file = new File(getSDCardPath() + File.separator + folderName+ File.separator);file.mkdirs();return file;}
在AppStart
中開啟了一個服務LogUploadService
用來上傳應用程序的日志。
在服務LogUploadService
被開啟後,根據情況進行如下幾種操作:
當某一個組件比如Activity,通過調用startService()方法來開啟一個服務時,系統會調用onStartCommand()方法。一旦這個方法執行之後,服務就會被開啟並在後台獨立的運行。如果你實現了這個方法,你必須在任務完成後通過調用stopSelf()
或者stopService()
來停止該服務。(如果你僅僅只想提供綁定,你不需要實現這個方法)。
日志上傳的操作,封裝在了OSChinaApi中,並且通過report來區分是bug還是反饋意見。
/*** BUG上報** @param data* @param handler*/public static void uploadLog(String data, AsyncHttpResponseHandler handler) {uploadLog(data, "1", handler);}/*** 反饋意見** @param data* @param handler*/public static void feedback(String data, AsyncHttpResponseHandler handler) {uploadLog(data, "2", handler);}
uploadLog方法:
private static void uploadLog(String data, String report,AsyncHttpResponseHandler handler) {RequestParams params = new RequestParams();params.put("app", "1");params.put("report", report);params.put("msg", data);ApiHttpClient.post("action/api/user_report_to_admin", params, handler);}
ApiHttpClient的post方法:
public static void post(String partUrl, RequestParams params,AsyncHttpResponseHandler handler) {client.post(getAbsoluteApiUrl(partUrl), params, handler);log(new StringBuilder("POST ").append(partUrl).append("&").append(params).toString());}
getAbsoluteapiUrl方法:
public static String getAbsoluteApiUrl(String partUrl) {String url = partUrl;if (!partUrl.startsWith("http:") && !partUrl.startsWith("https:")) {url = String.format(API_URL, partUrl);}Log.d("BASE_CLIENT", "request:" + url);return url;}
API_URL的值:
private static String API_URL = "http://www.oschina.net/%s";
階段一:一個簡單的天氣預報應用的完整實現過程(二),階段天氣預報“階段一”是指我第一次系統地學習Android開發。這主要是對我的學習過程作個記錄
Android5.x Notification應用解析 Notification可以讓我們在獲得消息的時候,在狀態欄,鎖屏界面來顯示相應的信息,很難想象如果沒有Not
Android簽名機制之---簽名過程詳解 一、前言 又是過了好長時間,沒寫文章的雙手都有點難受了。今天是聖誕節,還是得上班。因為前幾天有一個之前的同事,在申請微信SDK
如何取得nginx做反向代理時的真實IP?nginx做反向代理時的真實IP.pdf1.編譯對於client->nginxreverseproxy->apach