安卓计步器是如何实现计步的
開發環境
由于要用JAVA開發后端因此JDK必不可少,然后下載androd studio即可。SDK
幾種APP開發模式
Native App (原生軟件)APP應用所有的UI元素、數據內容、邏輯框架均安裝在手機終端上。
用安卓做個客戶端的殼訪問服務器式開發模式
安卓開發必備知識
Android開發目前還是需要使用java語言的,如果不需要很復雜的功能,那么掌握java,懂得xml就可以做一個本地的AndroidApp,如果需要上網功能,可能同時需要HTML,CSS,javascript,SQL。學習 Java 只是基礎,學習 SDK的使用方法才是開發安卓應用最關鍵的
大體來說,開發一個app從設計到最終實現需要你懂得以下幾個必要方面:
1、前期需求規劃與信息——首先,開發一個Android App軟件,你需要制定出一個完整的需求文檔,功能文檔,流程圖,時序圖。
2、交互設計、UI設計——手機AndroidApp開發需要設計出基本且完善的原型圖和app基礎的交互設計效果之后,再根據這些設計出完整的UI界面
3、使用ADT(抽象數據類型)之類的開發環境進行app軟件開發,你最基本的也得掌握java語言,熟悉android環境和機制。
4、如果不是單機版的app,需要用到服務器,那你還得掌握WebService相關知識和開發語言,常用的有ASP.Net,PHP,JSP等。
5、熟悉并能開發數據庫。
6、對于手機安卓app的開發,某些功能需要做算法,這還需要一定得專業知識尤其是數學基礎。
7、熟悉API接口開發,這里包括你自行開發API的能力以及調用第三方API的經驗。
8、熟悉TCP/IP,socket等網絡協議和相關知識。
9、熟練掌握App發布的流程,真機調試技巧,證書,打包,上架,一個完整的Android 手機App才能安全上架。
SDK:軟件開發工具包(Software Development Kit)一般都是一些軟件工程師為特定的軟件包、軟件框架、硬件平臺、操作系統等建立應用軟件時的開發工具的集合。包括廣義上指輔助開發某一類軟件的相關文檔、范例和工具的集合。
Android SDK 就是 Android 專屬的軟件開發工具包。
主要作用包括:
1.提供基礎類庫和官方推薦的附加類庫
調用電話/調用相機/相冊選擇等都是由基礎類庫android.jar提供的v4包v7包都是官方推薦的附加類庫
2.編譯工具
java編碼文件通過編譯工具編譯成Darvit虛擬機能夠讀取的dex文件,Android4.4后使用Art虛擬機,運行效率得到極大的提高
3.調試開發工具
提供了模擬器等調試開發工具
需求案例
2018年平安銀行產品經理和開發人員打架事件受到廣泛的關注,主要是由于不懂技術的產品經理提出奇葩需求:app的主題顏色能夠根據手機殼的顏色變化而變化。我們一個需求的實現高度依賴于SDK,SDK提供了相關API我們就能做,如果沒有提供我們就做不了,因此該開發人員在拒絕該需求的時候解釋說沒有提供接口,這里就是說SDK沒有提供相關的API來做這個需求。
Android SDK 中提供的面向硬件的特性
android.hardware.Camera
允許應用程序與相機交互的類,可以截取照片、獲取預覽屏幕的圖像,修改用來治理相機操作的參數。
android.hardware.SensorManager
允許訪問 Android 平臺傳感器的類。并非所有配備 Android 的設備都支持SensorManager 中的所有傳感器
android.hardware.SensorListener
在傳感器值實時更改時,希望接收更新的類要實現的接口。應用程序實現該接口來監視硬件中一個或多個可用傳感器。
android.media.MediaRecorder
用于錄制媒體樣例的類, 可以分析音頻片段以便在訪問控件或安全應用程序時進行身份鑒定。例如,它可以幫助您通過聲音打開門,以節省時間,不需要從房產經紀人處獲取鑰匙。
android.FaceDetector
允許對人臉(以位圖形式包含)進行基本識別的類。不可能有兩張完全一樣的臉。可以使用該類作為設備鎖定方法,無需記密碼 — 這是手機的生物特征識別功能。
android.os.*
包含幾個有用類的包,可以與操作環境交互,包括電源管理、文件查看器、處理器和消息類。和許多可移動設備一樣,支持 Android 的電話可能會消耗大量電能。讓設備在正確的時間 “醒來” 以監視感興趣的事件是在設計時需要首先關注的方面。
java.util.Date
java.util.Timer
java.util.TimerTask
當測量實際的事件時,數據和時間往往很重要。例如,java.util.Date 類允許您在遇到特定的事件或狀況時獲取時間戳。您可以使用 java.util.Timer 和java.util.TimerTask 分別執行周期性任務或時間點任務
Android SDK 中提供的面向軟件的特性
Android作為一個SDK,就需要提供給開發者在開發產品過程中實現一個基本功能所需的基本開發組件,而這些組件就是Activity,Service,Broadcast和ContentProvider
JDK
JDK全稱為Java開發工具包,主要作用包括:
1.提供基礎類庫
由rt.jar提供了基礎類的API,如果基礎類沒有只能由jar包的擴展類來提供
2.JVM[JAVA虛擬機]
class文件通過JVM"翻譯"成機器能夠識別的二進制的編碼,充當著機器和虛擬機之間的橋梁
3.編譯器
將java編碼"翻譯"成JVM能夠識別的成class文件
4.調試開發工具
提供debug調試工具等
跨平臺
Java之所以能實現其跨平臺的屬性其JVM功不可沒,不管你是win、mac還是Linux系統,只要安裝了JDK,就能跨平臺運行class文件。JVM做了中間的橋梁,所以JVM是很牛逼的東西,可惜的是我國真正去研究JVM的人很少。
Android SDK和JDK區別和聯系
1.Android SDK的基礎類庫[android.jar]參考了大部分的JDK基礎類庫[rt.jar],在此基礎上進行的一些修減,增加了Android特有的也刪除了JDK的一些基礎類,也有改造了一些類。Android各版本對應的SDK和JDK版本
2.Android SDK不包括虛擬機但JDK包括虛擬機,Android的Darvit&ART虛擬機安裝在Android設備上,Android是不存在main方法的入口這種說法的。
3.Android SDK編譯工具[Gradle]是將java文件編譯成Darvit&ART虛擬機能夠讀取的apk文件,JDK編譯工具將java文件編譯成JVM虛擬機能夠讀取的class文件。apk文件本質上就是zip包其中類主要編譯在dex文件中,dex文件由class文件轉化而來,因此apk的編譯程序比war包[將class文件打包,用于部署在服務器]編譯程序要多且要慢。
android中JDK和SDK和API的區別
一、 SDK
sdk,就是軟件開發包,是一個廣義的概念,任何編程工具幾乎都可以看成是SDK。單單說SDK,范圍太大。如果是Android sdk,就可以理解是安卓機器的操作系統,類似Windows操作系統。沒有Android sdk,就無法進行Android開發。簡言之,jdk是sdk的一種。
二、SDK和API
SDK和API的區別SDK相當于開發集成工具環境,API就是數據接口。在SDK環境下調用API數據
實際上SDK包含了API的定義,SDK又不完完全全只包含API以及API的實現,它是一個軟件工具包,它還有很多其他輔助性的功能。
通俗語言解釋API前端調用后端數據的一個通道,就是我們俗說的接口,通過這個通道,可以訪問到后端的數據,但是又無需調用源代碼。
三、JDK
JDK:開發JAVA程序的開發包,JDK里面有JAVA的運行環境(JRE),包括client和server端,需要配置環境變量
c++與java的幾個不同點
1—— c++有頭文件 而JAVA中是import
a:Java里有package關鍵字的用法,在寫的程序第一行使用package關鍵字來聲明一個包。包就是一個文件夾,它將源代碼文件(.java)、編譯后的文件(.class)和其他的一些用到的文件有組織的放在一起編譯器會在import導入的包里選擇與類名對應的包,而#include則是編譯器將其他文件的內容載入進來。
b:頭文件就是包含在C++程序中的別人寫好的一些東西,里面包含一些函數和一些特定的功能,比如一般使用的cout<< cin>> endl 等這些東西都包含在iostream里,sqrt,sin, cos等數學相關的函數都包含在cmath里。 在c++里有一個經典的命名:using namespace std;這行代碼使得我們在使用cin、cout、endl……時不用加std::的前綴常常要用到的一些函數,或定義,或習慣,也可以自已做成一個頭文件,在編程中引用,這樣可以減少很大的不必要的重復工作量。
c語言里頭的頭文件里放的 還是源代碼,而java引入的包是被編譯過的*.class文件并且JAVA的包 絕對是以類為單位的…也就是個類是一個*.class文件多個類 組成一個包而C++是 可以一個頭文件中放函數 放常量 放類
2——代碼格式
C/C++程序基本上是由n個函數組成,主函數調用其他函數實現所需功能。
Java程序是由n個類、m個方法組成,某個public類的主方法調用當前類的方法,或是調用其他類的公有(public)方法實現所需功能。Java的m個方法類似于C/C++的n個函數,只不過是將這m個方法放到n個類里,目錄結構更清晰一些。
3——.錄入輸出
c++的錄入輸出靠輸入流cin,輸出流cout、cerr、clog實現,需要寫#include。
Java語言里沒有像c++那樣一個函數就完成錄入,它的錄入使用了一些基礎類,比如:
首先導包import java.util.Scanner;然后在方法內使用以下語句進行錄入
4.——編譯結果
a::c/c++編譯的最終結果是一個程序生成一個exe文件。
b::Java編譯結果是一個程序中有多少類就生成多少個與類名 相同的class文件。
5——指針問題
c/c++的引用,它跟java的引用完全不是一個東西,c/c++的引用是同一塊內存的不同名字。而java的引用是指向一個對象,引用本身也占用了內存
a:首先,列舉一下能對指針進行的一些常見操作:
指向一個對象,如 Person *p = new Person….;int *iv = new int….
對指針所指的對象進行操作:P->getAge();
b:指向一個對象,如Person p = new Person…
調用對象的方法,p.getAge();
指向另外一個對象,Person p1 = new Person…; p = p1;
弄懂 JRE、JDK、JVM 之間的區別與聯系
JDK>JRE>JVM(開發工具包>運行環境>虛擬機)
JVM : (Java Virtual Machine),就是我們耳熟能詳的 Java 虛擬機。它只認識 xxx.class 這種類型的文件,它能夠將 class 文件中的字節碼指令進行識別并調用操作系統向上的 API 完成動作。所以說,jvm 是 Java 能夠跨平臺的核心,具體的下文會詳細說明。
JRE : (Java Runtime Environment), Java 運行時環境。它主要包含兩個部分,jvm 的標準實現和 Java 的一些基本類庫。它相對于 jvm 來說,多出來的是一部分的 Java 類庫。
JDK : (Java Development Kit),Java 開發工具包。jdk 是整個 Java 開發的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。
顯然,這三者的關系是:一層層的嵌套關系。JDK>JRE>JVM。
jdk 是我們的開發工具包,它集成了 jre ,因此我們在安裝 jdk 的時候可以選擇不再安裝 jre 而直接使用 jdk 中的 jre 運行我們的 Java 程序。(但是大部分人都默認將兩個都裝上了)。但是如果你的電腦不是用來開發 Java 程序的,而僅僅是用來部署和運行 Java 程序的,那么完全可以不用安裝 jdk,只需要安裝 jre 即可。
硬件
計步器用的是安卓手機自帶的傳感器,目前所知有TYPE_STEP_DETECTOR和TYPE_STEP_COUNTER(會自動返回一個從自啟動進程以來到目前為止的累計步數 貌似不用啟用service),sevice是一種服務,保持進程在后臺依然可以運行
Android SDK 中提供的面向軟件的特性(生命周期)
activity生命周期介紹(為什么要有生命周期)
Activity生命周期并不僅僅在用戶運行應用程序之后才開始生效,事實上它也影響著用戶切出以及切回應用時得到的不同反饋。當我們開發一款應用時,首先需要牢記一點:用戶會經常在執行過程中、在我們的應用與其它應用之間頻繁切換。取決于用戶的操作方式,同一款應用程序有時在前臺運行、有時則在后臺運行。大家必須保證自己的應用能夠就會這類情況,并在此類切換過程中及時保存并恢復數據。(用戶在一個界面上點擊一下,然后程序在后臺開啟一個線程去加載數據,加載完成后通知界面顯示數據,如果這些數據在退出App情況下也需要的話,還要把這些數據保存到本地文件中)
為了控制Activity處于不同狀態下時應用程序的運行方式,例如當用戶切出或者切回應用,大家可以選擇多種處理方法。這類方法也就是Activity生命周期回調方法。Android系統會在我們的Activity進入某種特定狀態后調用這些方法,從而通過一系列步驟確保我們的應用程序能夠繼續起效、不至于丟失數據而且在用戶不與之交互時不會使用非必要性資源。每一種回調方法都會讓我們的應用進入一種可能的狀態。
如果大家之前曾經接觸過Java應用程序的編程工作,那么應該已經發現Android應用程序的啟動遵循另一種方式。與Java應用直接使用主方法不同,Android在啟動后會首先執行主Activity類中的onCreate方法。請記住,我們已經在清單中將該類指定為主啟動Activity。Activity會首先回調onCreate方法,相當于重復用戶啟動應用程序后的流程。這時候onCreate方法會使應用程序進入Created狀態。
開發者指南當中通過示意圖以直觀方式介紹了生命周期、回調方法以及狀態的概念。其中onResume方法負責提供Resumed狀態,這時我們的應用程序可以接受用戶的直接操作。其它各類回調方法都以onResume為核心,即將應用程序引導至Resumed狀態或者從該狀態脫離、啟動該狀態或者將其停止。
對于大部分應用程序來說,我們只需要使用一部分回調方法,但最起碼要用到onCreate。雖然使用頻率不高,但了解全部回調及狀態的作用將幫助我們了解自己的應用程序在運行及停止運行時,Android系統會受到怎樣的影響。一般情況下,大家需要保證用戶能夠在任何操作過程切換出去之后、都能順利恢復到之前的運行狀態;如果他們通過導航選擇前進或者后退,應用則需保存全部必要數據并釋放不必要占用的硬件資源。
基于場景解讀Android四大組件
我們知道一個App里面最常見的交互流程是這樣的:用戶在一個界面上點擊一下,然后程序在后臺開啟一個線程去加載數據,加載完成后通知界面顯示數據,如果這些數據在退出App情況下也需要的話,還要把這些數據保存到本地文件中。我們把這個流程分解成下面四個步驟:
1、前臺(界面展示);
2、后臺(數據加載);
3、通信(前臺和后臺通信);
4、存儲(數據存儲);
到這里可能大家會明白我想說的是什么了。這里的每一步其實就對應了一個組件,Activity就代表了前臺所要提供的功能,主要負責界面的展示和用戶的交互。Service就代表了后臺所要提供的功能,主要負責一些耗時工作如網絡請求,文件讀寫的處理。Broadcast就代表了通信所要提供的功能,主要負責Activity和Service之間(當然也可以是Activity和Activity,Service和Service)的通信。ContentProvider就代表了存儲所要提供的功能,主要負責數據在磁盤的讀寫。
這里也許會有很多人不認同我的說法,比方說后臺任務不一定要用Service啊,我自己搞個線程池或者開個進程也可以,消息通信也不一定需要Broadcast,我自己用Handler或者AIDL也可以做,存儲也不需要ContentProvider,我自己寫一套文件讀寫框架也可以。如果你這樣想,也是可以的,但是我這里說了,我只是基于使用場景來談這四個組件,從App層面考慮,Android作為一個SDK,就需要提供給開發者在開發產品過程中實現一個基本功能所需的基本開發組件,而這些組件就是Activity,Service,Broadcast和ContentProvider,少一個不行,多一個沒必要。當然這四大組件其實也是Android為了方便開發者使用而提供的,你可以不用,自己重寫一套來實現我上面說的前臺,后臺,通信和存儲這四步(現在很多App都是這么干的)。但終歸是要實現這四大功能,一個都不能少。
Activity使用場景解讀
這張圖大家應該很熟悉了,這里我按使用場景來把它們分成三組:
onCreate和onDestroy
onStart、onRestart和onStop
onResume和onPause
第一組使用頻率最高,為什么?因為它的使用場景是最多的,在一個App里面我們會經常需要打開(startActivity)和關閉(finish)一個頁面。onCreate是Activity生命周期里面的第一步,當我們進入到這一步時就表示一個Activity實例對象(從Java的角度看)已經產生了,當我們New了一個Java對象之后,首先要做的肯定是對其進行初始化了,那么onCreate就是Android提供給開發者用來對Activity實例對象中的成員做初始化的。Tips:Android為了方便對Activity組件的管理以及開發者使用,對Activity做了封裝,開發者不能直接new一個Activity對象(你也可以直接new,但是new出來的對象不會被Android管理,也就失去了界面的展示和交互的功能,跟普通Java對象無異).
在onCreate里面一般我們會做View的初始化操作,比如添加View(setContentView,addView等)和View中數據的填充(setText,setImage等),那么問題來了:為什么對View的初始化要放在這里,可不可以放到其他地方(onStart或者onResume)?答案是肯定的,但是我們不建議這么做,因為放在onCreate里面可以保證初始化操作只做一次,而放到其他地方可能會調用多次,當然你可以添加一個flag來標記是否已經做過初始化,這樣就可以保證放在onStart或者onResume里面也只做一次初始化,但是這樣不覺得多此一舉么?既然onCreate已經幫我們實現了這么一個功能,為啥不用呢,當然如果你有特殊需求,另當別論。
還有就是在onCreate里面有個savedInstanceState參數,這個主要用于你的Activity在非正常情況下被銷毀前幫你自動保存的一些數據,這些數據會在這個Activity被重新創建時用到,因此Android將這個參數放在了onCreate里面。注意,我這里說的是非正常情況銷毀Activity,這種場景比較多,比如系統內存不夠用,系統語言改變,屏幕方向改變等,如果你不清楚哪些是非正常情況,沒關系,只要清楚正常情況就行了,其他的自然就都可以認為是非正常場景下的Activity銷毀行為。那么正常情況是什么?用戶主動意愿想要銷毀Activity就是正常情況,這種場景很少,就兩種:調用finish和帶特殊啟動模式的startActivity方法。那么對于非正常情況下的onCreate我們在里面又該如何使用這個savedInstanceState?那么就要搞清楚savedInstanceState會保存到哪些數據,有兩種:系統幫你自動保存的和你自己保存的。系統只會保存它認為有必要保存的(比方說EditText里面的內容,CheckBox的Check狀態,Fragment實例等),但是很多童鞋不知道Activity會自動保存其中的Fragment實例,onCreate寫成這樣子:
onStart、onRestart和onStop
說實話這三個回調接口在實際使用場景中并不多,對onStart、onRestart和onStop的使用可以從是否可見這點來找到它的正確使用姿勢。這里舉幾個常用的場景:
對數據的時效性要求較高。以新聞類App為例:Activity A代表新聞列表,點擊列表中的一個Item進入到Activity B新聞詳情,在從B返回到A的時候為了保證用戶能看到最新的新聞,就需要從服務器拉取最新的新聞列表數據并填充到Activity A,那么這個工作就可以放在onStart里面,當然你也可以放在onRestart里面,但是activity首次加載啟動的時候不會調用onRestart,所以也就不會去拉取新聞列表數據。
需要顯示動畫效果。有些activity需要顯示一些動畫來幫助提升用戶體驗,但是當我們從該頁面進入到一個新頁面時,由于該頁面已經不可見了,所以就可以把當前頁面中的動畫給關掉以節省系統資源,而這個工作就可以放在onStop中進行。
onResume和onPause
這兩個接口使用的頻率比上一組要高,對onResume和onPause的使用可以從可以從是否獲得焦點(焦點即代表是是否可交互)這點來找到它的正確使用姿勢,這里也舉幾個常見場景:
結束占用CPU的動畫或者其他正在運行任務,這種在使用地圖SDK的時候比較常見:
Service使用場景解讀
Service是Android提供給開發者的一個組件,主要用于后臺一些耗時任務的處理。其實Android系統中已經存在了很多這樣在后臺執行一些特定任務的系統級Service,比方說與我們開發中打交道最多的ActivityManager,WindowManager,PackageManager和InputManager等等。
這些方法能夠讓我們的應用程序在可能的狀態之間進行切換,而且某些情況下切換速度會很快。通常來說,大家可以認為自己的應用程序始終處于resumed、paused或者stopped這三種狀態之下,因為其它狀態都是暫時性的。從圖中可以看出Service的生命周期會根據啟動方式的不同有不同的生命周期回調。其實startService和bindService的區別就是該service是否可以和啟動它的組件(比如activity)通信,因為bindService可以拿到Service的binder,binder就是用來實現IPC(進程間通信)的嘛。下面我們具體分析下每個生命周期回調:
onCreate
該接口是在Service實例被創建時調用,這里的Service實例跟Activity實例不一樣,我們知道Activity實例根據不同的啟動模式可以有一個或者多個實例,但是,Service雖然也有兩種啟動方式,在整個系統中卻只會有一個Service實例。為什么呢?換個角度看,這就好比PC端的C/S模式,使用一個服務端去處理多個客戶端的請求,這里就對應一個Service去處理來自多個Activity的請求嘛,沒必要搞多個,浪費資源,而且你會發現系統級Service其實也都只有一個實例。那么在onCreate里面我們可以做些什么呢?當然是初始化,比如創建數據緩存,線程池等等。Android系統給我們提供了一個IntentService,我們可以參考它的實現方式來做一些初始化操作,IntentService的onCreate源碼如下: 這里為什么要創建新的線程或者線程池呢?因為Service默認是在主線程中執行的,所以我不建議你把一個后臺任務放在Service中的主線程執行,因為那樣就失去了Service存在的初衷,還不如直接放在Activity里面做,除非你想要提升App進程的優先級,防止App退到后臺被殺掉。
onStart
該接口是在調用startService方法時調用的,我們的后臺任務一般都會放在這里執行,你可以通過intent獲取startService方法傳遞的參數,這里依然以IntentService為例看下它的實現方式:
onBind
該方法是在調用bindService方法時調用,如果使用bindService方式來啟動服務的話,一般發生在Activity需要與Service進行通信的場景(比如說音樂播放器app里面就會用到),而Android的IPC主要是通過binder來實現的(也可以通過socket,在系統服務用的比較多),所以這里方法的返回值就需要一個binder實例。這里簡單說下binder的實現機制(后續講Broadcast的時候我們在具體分析Android的IPC機制具體實現),其實就是一套PC上的C/S模式,用戶通過bindService接口獲取到Service的代理,然后通過這個代理來跟Service通信。我們這里用一段代碼來詳細說明下:
這里的代理分兩種:本地代理和遠程代理,它們是按照service和activity是否在同一個進程中來區分的(這里僅以activity和service通信為例來說明,其他場景原理類似),如果是在同一進程,那么這個代理對象mServiceProxy其實就是mService對象。而當它們不在同一個進程中時,mServiceProxy和mService就屬于不同進程空間中的對象,由于不同進程之間的數據不能直接訪問,所以這個時候binder driver就來充當一個中間橋梁的作用,來完成參數和返回結果等數據的傳遞(其實也就是在Linux內核空間開辟了一段共享內存),從而實現通信的目的。當然為了方便開發者使用binder,Android對binder的使用進行了一定的封裝,提供了一個AIDL。通過AIDL我們就只需關心service提供的功能接口,而不用去關心這些接口調用的具體細節。所以從這里也可以看出,對于一個好的產品,不管它的用戶群是普通用戶還是程序員,使用的便捷性都是一個很重要的指標。就好比現在市面上很多做SDK的,往往那些接口簡單,文檔清晰的SDK,用的人也會多一些。
onUnbind
該方法是在調用unbindService方法時調用,一般發生在activity中需要斷開與service的連接的場景。注意該接口有個返回值,默認為false。如果你想要在onRebind里面做一些事情的話,那么這里需要返回true。
onDestroy
該方法會在Service銷毀時調用,一般在這里我們會釋放一些在onCreate中進行初始化時所申請的資源,可以參考IntentService的實現方式:
Service使用場景
為了滿足開發者處理后臺任務的需要,Android提供了Service這個組件,同時為了方便開發者使用Service,又封裝了一個IntentService。當然,現在很多App在處理后臺任務的時候并沒有優先使用Service,而是自己實現了一套線程池機制或者使用Android提供的AsyncTask來執行后臺任務,這里我們來分析下他們各自的優劣:
Service的優點是系統原生支持,使用方便;創建進程方便;可以提供給系統內其他App使用;優先級高,當App退到后臺后不宜被殺死。缺點是由于啟動Service涉及到多次IPC,運行效率不高,而且受限于系統接口,使用不夠靈活。
線程池的優點是運行效率高,配置和使用靈活。缺點是多進程實現不方便, 由于Android實現了一套進程托管機制,我們不能直接創建一個新的進程,而只能通過四大組件的形式創建新的進程。
基于以上分析,我們可以看出,一般普通的異步任務,比如網絡請求,數據庫或者文件相關操作,我們都會使用線程池的方式來做,因為這樣使用的系統開銷小,運行效率高,而且隨著業務邏輯的復雜度增加,擴展性也更強。然而,對于一些特殊場景,比如進程保活,使用第三方SDK服務比如地圖,IM等,就需要使用Service來實現,因為這些服務一般與App主進程隔離開,需要運行在新進程中以防止App主進程發生異常崩潰時,牽連第三方服務也掛掉。
如何把傳感器的數據傳入app
這里使用了android SDK里的一個sensor類
-
大致思路
用SensorManager獲得該傳感器(用sensor_service返回一個sensorManager對象),然后為傳感器建立一個SensorEventListener(傳感器事件監聽器),這個監聽器中包含兩種需要實現的方法(nAccuracyChanged ,onSensorChanged ),方法規定了當傳感器值發生變化時,監聽器監聽到該事件于是采取操作,返回當前傳感器的值
- 補充下傳感器的工作原理: 傳感機是靠感知手機振動來實現計步的,電子計步器主要由震動傳感器和電子計數器組成。人在步行時重心都要有一點上下移動。 電子計步器的工作核心就是震動傳感器,它里面有一個機械的震子,運動時會產生上下震動,機器通過收集震子運動的頻率來計算數值 。
數據庫
Android 五種數據存儲的方式分別為:
作為一個完整的應用程序,數據存儲操作是必不可少的。因此,Android系統一共提供了四種數據存儲方式。分別是:SharePreference、文件存儲、SQLite、 Content Provider。對這幾種方式的不同和應用場景整理如下。
第一種: 使用SharedPreferences存儲數據
適用范圍:保存少量的數據,且這些數據的格式非常簡單:字符串型、基本類型的值。比如應用程序的各種配置信息(如是否打開音效、是否使用震動效果、小游戲的玩家積分等),解鎖口令密碼等
核心原理:保存基于XML文件存儲的key-value鍵值對數據,通常用來存儲一些簡單的配置信息。通過DDMS的File Explorer面板,展開文件瀏覽樹,很明顯SharedPreferences數據總是存儲在/data/data//shared_prefs目錄下。SharedPreferences對象本身只能獲取數據而不支持存儲和修改,存儲修改是通過SharedPreferences.edit()獲取的內部接口Editor對象實現。 SharedPreferences本身是一 個接口,程序無法直接創建SharedPreferences實例,只能通過Context提供的getSharedPreferences(String name, int mode)方法來獲取SharedPreferences實例,該方法中name表示要操作的xml文件名,第二個參數具體如下: Context.MODE_PRIVATE: 指定該SharedPreferences數據只能被本應用程序讀、寫。
Context.MODE_WORLD_READABLE: 指定該SharedPreferences數據能被其他應用程序讀,但不能寫。
Context.MODE_WORLD_WRITEABLE: 指定該SharedPreferences數據能被其他應用程序讀,寫
SharedPreferences對象與SQLite數據庫相比,免去了創建數據庫,創建表,寫SQL語句等諸多操作,相對而言更加方便,簡潔。但是SharedPreferences也有其自身缺陷,比如其職能存儲boolean,int,float,long和String五種簡單的數據類型,比如其無法進行條件查詢等。所以不論SharedPreferences的數據存儲操作是如何簡單,它也只能是存儲方式的一種補充,而無法完全替代如SQLite數據庫這樣的其他數據存儲方式。
第二種: 文件存儲數據
可以在設備本身的存儲設備或者外接的存儲設備中創建用于保存數據的文件。同樣在默認的狀態下,文件是不能在不同的程序間共享。
寫文件:調用Context.openFileOutput()方法根據指定的路徑和文件名來創建文件,這個方法會返回一個FileOutputStream對象。
讀取文件:調用Context.openFileInput()方法通過制定的路徑和文件名來返回一個標準的Java FileInputStream對象。
第三種:SQLite存儲數據
SQLite Database數據庫。Android對數據庫的支持很好,它本身集成了SQLite數據庫,每個應用都可以方便的使用它,或者更確切的說,Android完全依賴于SQLite數據庫,它所有的系統數據和用到的結構化數據都存儲在數據庫中。 它具有以下優點: a. 效率出眾,這是無可否認的 b. 十分適合存儲結構化數據 c. 方便在不同的Activity,甚至不同的應用之間傳遞數據。第四種:ContentProvider
Android系統中能實現所有應用程序共享的一種數據存儲方式,由于數據通常在各應用間的是互相私密的,所以此存儲方式較少使用,但是其又是必不可少的一種存儲方式。例如音頻,視頻,圖片和通訊錄,一般都可以采用此種方式進行存儲。每個ContentProvider都會對外提供一個公共的URI(包裝成Uri對象),如果應用程序有數據需要共享時,就需要使用ContentProvider為這些數據定義一個URI,然后其他的應用程序就通過Content Provider傳入這個URI來對數據進行操作。
總結一下,文件適用于存儲一些簡單的文本數據或者二進制數據,SharedPreferences適用于存儲一些鍵值對,而數據庫則適用于那些復雜的關系型數據。
SharedPreferences類介紹
Android平臺給我們提供了一個SharedPreferences類(是一種方法,就像content provider一樣是一種方法,具體是怎么存儲到硬件上的我們不用關心,只要知道是以xml文件存儲的就行了),它是一個輕量級的存儲輔助類,特別適合用于保存軟件配置參數和應用的一些常用配置。 例如,一些默認歡迎語、登錄的用戶名和密碼等比如Activity狀態,Activity暫停時,將此activity的狀態保存到SharedPereferences中;當Activity重載,系統回調方法onSaveInstanceState時,再從SharedPreferences中將值取出。SharedPreferences 可以用來進行數據的共享,包括應用程序之間,或者同一個應用程序中的不同組件。比如兩個activity除了通過Intent傳
使用SharedPreferences保存數據, 其背后是以“鍵-值”對的方式用xml文件存放數據,文件存放在/data/data//shared_prefs目錄下。提示最終是以xml方式來保存,整體效率來看不是特別的高,對于常規的輕量級而言比SQLite要好不少
如何利用xml存儲數據的
具體編程實現
ContentProvider使用場景解讀
ContentProvider在整個Android系統中扮演了數據管理的角色,負責整個Android系統中App數據的訪問和各App之間的數據共享,ContentProvider提供了一些通用的接口來實現對底層數據(其實是數據庫中的表結構數據)進行操作。
ContentProvider是什么?
ContentProvider是Android提供給上層的一個組件,主要用于實現數據訪問的統一管理和數據共享。這里的數據管理是通過定義統一的訪問接口來完成,如增刪改查。同時,它采用了類似Internet的URL機制,將數據以URI的形式來標識,這樣其他App就可以采用一套標準的URI規范來訪問同一處數據,而不用關心具體的實現細節。我們知道在Android系統中可能會涉及到一個App的數據被其他App使用的情況,比如通訊錄,日歷,短信等,這時就需要一套能實現數據共享的機制,這里的ContentProvider就可以提供該功能,其底層使用了binder來完成App進程之間的通信,同時使用匿名共享內存來作為共享數據的載體。當然為了保證數據訪問的安全性,ContentProvider還對每處的數據URI增加了權限管理機制,以控制該數據的訪問者及訪問方式。
最后再說下為何ContentProvider在我們平時開發App中使用的不多?其實,雖然ContentProvider具有數據管理和數據共享的功能,但是多半的優勢還是集中在數據共享上,在數據共享的前提下,這個數據管理的優勢也才能更加明顯。像一些系統內置應用,聯系人,日歷和短信,就比較適合使用ContentProvider,因為他們經常需要給其他App提供數據。而對于像普通App,一般出于安全原因,不會把數據提供給第三方App使用,而在App內部訪問數據庫的話,完全可以自己實現一套數據庫訪問框架,因為ContentProvider為了屏蔽數據庫的訪問細節,實質上是在其基礎上再封裝了一層接口而已,而對于App內部的數據庫訪問來說,沒有這個必要
用service實現計步器的后臺運行
這個問題相當于為什么當計步器轉入后臺程序的時候仍然可以實現計步的功能,這就引入了我本段要講的組件service。
-
講sevice之前先講一下何為后臺
安卓軟件所處的一種生命周期Activity一般有四種狀態:
(1)running:當Activity位于棧頂時,此時正好處于屏幕最前方,此時處于運行狀態;
(2)paused:當Activity失去了焦點但仍然對用于可見(如棧頂的Activity是透明的或者棧頂Activity并不是鋪滿整個手機屏幕) ;
(3)stoped:當Activity被其他Activity完全遮擋,此時此Activity對用戶不可見
(4)destoryed:當Activity由于人為或系統原因(如低內存等)被銷毀 ;
后臺即paused和stop狀態。 -
具體應用
一個service是一段長生命周期的,沒有用戶界面的程序,一個例子就是手機播放音樂時用戶可以進行其他應用的活動,或者鬧鐘關機之后仍然可以響。對service其實就是在主頁面基礎上(在oncreat中)寫一個intent,然后可以把service定義到onclick中(用intent轉換),service也有生命周期例如oncreat,onstart, -
支付寶和微信的計步原理
-
是怎么實現交互的
安卓需要用到一個組件叫activity,一個activity提供一個屏幕,用戶可以用來交互已完成某種任務,例如點擊、撥號拍照。由于安卓是事件驅動的,因此當你做操作的時候會對應一系列處理,最典型的就是點擊事件的設置,為監聽事件設置一個監聽器,當監聽器監聽到你的動作就會跳轉到該動作觸發的程序,這樣就完成了一次交互操作。 監聽器概念在安卓中非常重要,在上文中提到獲取傳感器數據時也用到了一個sensorlistener(是監聽傳感器的值是否發生改變) -
補充事件驅動的定義:
首先我們來給事件驅動編程下一個定義。事件驅動編程是一種編程范式,程序的執行流程是由動作(actions,例如用戶交互,其他線程發送的消息等等)觸發的事件(event)決定的。在這個意義上,Android是部分事件驅動:我們都知道的onClick監聽器或者Activity的生命周期,都是應用中由動作觸發的事件。我為什么說它不是純粹的事件驅動系統呢?默認情況下,每個事件被綁定在特定的controller上面,因此很難在其他地方使用該事件(例如onClick事件是定義為View服務的,因此它的使用范圍很有限)。
是如何獲得時間的
由于安卓中system類中提供獲取時間的方法(System.currentTimeMillis()),因此我們要做的就是開啟一個線程,無限循環該線程,在線程中用handler的message的通信機制,每隔一秒就會發出一個message,然后就可以主線程中處理消息并更新時間,在通過xml的設計顯示到界面上就行了。
計步器的各類性能
準確率方面
android機型眾多,傳感器的靈敏度不一,因此會出現各種計步數不同的現象
傳感器的選擇
由于android4.4 就支持stepcount了 因此可以直接接受返回值,省去了對于步數檢測的一系列算法
實現隔天清零以及查看歷史數據的操作
//emmm這個功能以后再學習吧
隔天清零 參考該篇博文
感覺這個博主的代碼很易懂,附傳送門~
這個是關于計步器的一篇論文
- 計步器的問題
安卓的計步傳感器,重啟數據清零,跨天數據不會清零,所以當天的數據需要自己計算.當天的最后一次步數 - 當天的第一次步數 = 當天的步數, 還要考慮重啟傳感器清零的情況."還有些手機殺掉進程可以獲取數據,但是隔天需要重新開啟進程,不然不會計步。"這個就是第一次打開注冊了讀取到當時的值了
首先拋出問題android4.4之后提供了兩個傳感器STEP DETECTOR 以及 STEP COUNTER,但是這兩個傳感器雖然可以很方便的提供給我們步數,但返回的步數是從開機以來的累計步數,隔天數據無法實現清零 ,并且關機之后無法實現
先來看下我們需要解決的點有:
1、步數從開機之后不斷累加,關機之后便清零,步數 不能隔天清零
2、不能查看歷史數據
數據的存儲
web app和原生app有三種區別:
1.開發方面有區別:
(1)原生APP:每一種移動操作系統都需要獨立的開發項目,iphone版本、Ipad版本、安卓版本。每種平臺都需要獨立的開發語言。Java(Android), Objective-C(iOS)等等。需要使用各自的軟件開發包,開發工具以及各自的控件。
(2)開發成本高、開發速度慢、維護成本高。三個平臺(IOS、安卓、windows)的規則、推廣、運營都不相同。官方應用商店對APP上線審核流程比較復雜而且很慢,會嚴重影響APP的發布上線。
(3)Web App :因為運行在移動設備的瀏覽器上,所以只需要一個開發項目。可以通過HTML、 CSS或者JavaScript來進行WebAPP的開發。開發成本低、開發速度快。
2.功能有區別:
(1)原生App:原生APP是一個系統性的應用程序,可以類比于電腦上的軟件。原生app可以調用移動終端的硬件設備, 比如:麥克風、攝像頭、短信、GPS、藍牙、重力感應等。實現功能豐富
(2)Web App:Web APP可以類比于電腦上的網頁。Web APP更多是頁面展示類的APP。只能使用有限的移動硬件設備功能。更多用于頁面展示,側重于簡單的交互,無法使用很多硬件設備獨特的功能。
有關android四大組件引用于https://www.jianshu.com/p/9612c33686b9
https://blog.csdn.net/chaoyu168/article/details/52997036Android SDK上手指南:Activity與生命周期
總結
以上是生活随笔為你收集整理的安卓计步器是如何实现计步的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 非线性系统稳定性理论分析、设计方法
- 下一篇: IE浏览器解决无法识别js中getEle