安卓基礎筆記

安卓主要由四層構成:
Applications 應用程序層
ApplicationFramework 程序框架層
Libraries 核心類庫
LinuxKernel Linux內核


各目錄作用:
add-ons android拓展庫
docs android相關文檔
extras android附加支持文件(驅動)
platforms androidSDK相關文件
platform-tools 存放工具平臺
samples SDK自帶的默認示例工程
sources api源代碼
system-images 系統中用到的圖片
temp 系統中臨時文件
tools 各類工具


(android調試橋)ADB工具常用命令:
adb start-server 開啓adb服務
adb device 列出可用的模擬器
adb logcat 查看日誌
abd kill-server 關閉服務
adb shell 掛載到linux的空間
adb install <應用程序> 安裝應用程序
adb -s <模擬器名稱> install <應用程序> 安裝到指定的模擬器
adb uninstall <程序包名> 卸載指定的應用程序


ApplicationName 應用名稱
ProjectName 項目名
PackageName 包名
minimumRequiredSDK 最兼容的版本
TargetSDK 最匹配的版本
compilewith 那個版本SDK進行編譯
Theme UI主題


src  所有java代碼的地方
geb 自動生成R.java文件
Android4.1.1 用的SDK文件
assets 用於存放一些隨陳旭打包的文件
bin 生成apk文件測試包
libs jar包
res 圖片,佈局,字符串
androidmanifese.xml 重新編譯最高最低版本
proguardproject.txt 混淆代碼工具
project.properties 安卓運行環境


MainActivity.java 文件
public class MainActivity extands Activity{
protected void oncreate(Bundle s){
super.onCreate(s); //記住佈局
setContentView(R.layout.UI); //打開佈局
}
}


佈局的類型
一、相對佈局(RelativeLayout)
android:layout_alignParentLeft 是否跟父佈局左對齊
android:layout_alignParentTop 是否跟父佈局頂部對齊
android:layout_alignParentRight 是否跟父佈局右對齊
android:layout_alignParentBouttom 是否跟父佈局底部對齊
android:layout_toRightOf 在指定控件右邊
android:layout_toLeftOf 在指定控件左邊
android:layout_above 在指定控件上邊
android:layout_below 在指定控件下邊
android:layout_alignBaseline 與指定控件水平對齊
android:layout_alignLeft 與指定控件左對齊
android:layout_alignRight 與指定控件右對齊
android:layout_alignTop 與指定控件頂部對齊
android:layout_alignBottom 與指定控件底部對齊
二、線性佈局(LinearLayout)
android:orientation="vertical"; 垂直佈局
android:orientation="horizontal"; 水平佈局
三、表格佈局(TableLayout)
TableRow 行數對象
android:stretchColumns="n" 爲第多少列拉伸
android:layout_column="n" 列數屬性
四、網格佈局(GridLayout)
android:layout_gravity 對齊方向
android:columnCount="n" 網格列數
android:layout_column="n" 該控件在第幾列
android:layout_rowSpan="n" 該控件佔幾行
android:layout_columnSpan 該控件佔幾列
五、幀佈局(FrameLayout)
android:layout_width="dp" 佔據的寬度
android:layout_height="dp" 佔據的長度
六、絕對佈局(AbsoluteLayout)
android:layout_x="dp" 所在橫座標的位置
android:layout_y="dp" 所在縱座標的位置




各類控件屬性
TextView 文本控件
EditText 編輯框
Button 普通按鈕
RadioButton 單選按鈕
android:drawableTop="@android:drawable/ic_med"設置文字上方的圖片
ProgressBar 進度條(不可更改)
SeekBar 進度條(可通過滑動更改)
style="?android:attr/progressBarStylrHorizontal"設置進度條爲條形(還有環形進度條)
OnSeekBarChangeListener //監聽滑塊位置
setMax() //設置進度條最大值
setProgress() //設置當前進度
getProgress() //獲取當前進度
ListView 列表框
android:cacheColorHint //設置拖動的背景色
android:divider //設置分界線
android:dividerHeight //設置分割線高度
android:listSelector //設置選中時顏色
android:scrollbars //設置滾動條
android:fadeScrollbars //是否自動隱藏顯示
樣式調用:style="@style/TextStyle"
環境測試
一、Junit
<application><uses-library android:name="android.test.runner"/></application>
<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="需要測試的包名稱" />
assertEquals(期望值,真實值);
開始測試:Run As→Android Junit Test
二、LogCat
五種級別:Verbose黑色、Debug藍色、Info綠色、Warming橙色、Error紅色
Log.v||d||i||w||e顯示全部信息||顯示調試信息||一般信息||警告信息||錯誤信息顯示
三、Toast
Toast.makeText(javaname.this,"信息",0||1).show();0表示短,1表示長


事件:
onKeyDown(int,event)對應鍵按下事件
onKeyUp(int,event)對應鍵鬆開事件
onTouchEvent(event)對應點擊屏幕事件


Activity生命週期:
onCreate(Bundle s) 創建時執行
onStart() 可見時執行
onRestart() 回到前臺,再見到時執行
onReause() 獲取焦點時執行
onPause() 失去焦點時執行
onStop() 用戶不可見進入後臺時執行
onDestroy() 銷燬時執行


不希望橫豎屏幕時Activity被重建
android:configChanges="orientation|keyboardHidden|screenSize"
一直處於豎屏
android:screenOrientation="portrait"
一直處於橫屏
android:screenOrientation="landscape"


點擊事件的四種方法:
onClick指定方法名稱


創建內部類實現OnClickListener接口
{...
b.setOnClickListener(new m());
}
private class m implements OnClickListener{
public void onClick(View v){
switch(v.getId()){
case R.id.b:
點擊事件
break;
}
}
}


主類中實現OnClickListener
主類 implements OnClickListener
{...
b.setOnClickListener(this);
}
public void onClick(View v){
switch(v.getId()){
case R.id.b:
點擊事件
break;
}
}


匿名內部類:
{...
b.setOnClickListener(
new OnClickListener(){
public void onClick(View v){
點擊事件
}
}
);
}


Activity的啓動模式:
<activity>中,設置android:launchMode="standard||singleTop||singleTask||singleInstance"
分別表示:默認啓動方式,完全新建||重複利用||重用刪上||重用僅存


Intent的調用:
顯示調用(主要用於打開本應用Activity):
Intent i.setClassName("包名","包名+class名稱");//異包調用
startActivity(i);//開啓Activity


Intent i=new Intent(this,b.class); //同包調用
i.putExtra("key","value"); //傳遞字符串值
startActivity(Intent i); //打開這個Intent


Intent ii=getIntent();
String data=ii.getStringExtra("key");//調用的包中取出數據
如果傳遞多個數據,利用putExtras(Bundle);傳遞數據,Bundle.putString||Int("key","value")
多個數據接收,Intent ii=getIntent();
Bundle data=ii.getStringExtras();
String n=data.getString("key")




隱式調用(主要用於打開其他應用組件,自己的也可以):
清單文件中<intent-filter>
<action android:name="包名+class名稱">
<category android:name="android.intent.category.DEFAULT" />
//默認的category會自動將這個category添加到Intent中
</intent-filter>
Intent i=new Intent();
i.setAction("name");
startActivity(i);//開啓Activity


Intent回傳數據
Intent i=new Intent(this,b.class);
startActivityForResult(Intent i,int n); //Intent,請求碼


protected void onActivitResult(int requestCode,int resultCode,Intent data){
super.onActivityRequest(requestCode,resultCode,data);
String data=data.getStringExtra("key");
}


另一個java中
Intent i=new Intent();
i.putExtra("key","value"); //傳輸的密碼和內容
setResult(int n,Intent i); //結果碼,intent
finish(); //銷燬當前Activity


數據存儲的五種方式:


文件儲存:以IO流的形式儲存在本地文件中,分爲內部儲存,和外部儲存。
內部儲存:放在data/data/packagename/files/目錄下,應用卸載時與之同炬
主要的方法:
openFileOutput(String name,int mode); //儲存文件名,模式
MODE_PRIVATE只能被該文件讀寫
MODE_APPEND該文件內容可以追加
MODE_WORLD_READABLE可被其他文件讀取
MODE_WORLD_WRITEABLE可被其他應用寫入
openFileInput(String name); //打開的文件名稱


外部儲存:放在mnt/sdcard/目錄下,屬於永久儲存
主要的方法:
Environment.getExternalStorageDirectory() //獲取SD卡根目錄
String Environment.getExternalStorageState() //檢測外圍設備是否可用
String n=Environment.getExternalStorageState()
n.equals(Enviroment.MEDIA_MOUNTED||BAD_REMOVAL||CHECKING)//以掛載||沒掛載||正在檢查


外部儲存需要的權限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />//寫
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />//讀


序列化:
XmlSerialize X=Xml.newSerializer(); //創建XmlSerializer對象
X.setOutput(fileOutputStream,"utf-8"); //設置文件編碼方式
X.startDocument("utf-8",true); //寫入XML文件標識
X.startTag(null,"persons"); //開始節點
X.attrribute(null,"key","value") //標籤內寫入
X.text("value"); //寫入內容
X.endTag(null,"persons"); //結束節點
X.endDocument(); //結束


XML文件解析:DOM解析、SAX解析、PULL解析。適合較小的xml文件,消耗內存||解析超大的xml文件,不必等到加載結束顯示,不存在佔用內存,無法進行增刪改查。||pull最常用android和javaee中


PULL解析
XmlPullParser.START_DOCUMENT //文檔的開始
XmlPullParser.END_DOCUMENT //XML文檔的結束
XMLPullParser.START_TAG //開始節點
XMLPullParser.END_TAG //結束節點




XmlPullParser pull=Xml.newPullParser(); //得到XmlPullParser對象
pull.setInput("文件名稱","utf-8"); //文件的輸入編碼
int n=pull.getEventType(); //得到類型
while(n!=XmlPullParser.END_DOCUMENT){ //直到結束
switch(n){
case XMLPullParser.START_TAG:
if("name".equals(pull.getName())){
this.name=pull.nextText();
}
if("id".equals(pull.getName())){
this.id=pull.getAttributeValue(0);
}


···(XMLPullParser.END_TAG)




n=pull.next(); //獲取類型給予n
}
}




SharedPreferences:以key/value鍵值對應形式保存,文件位置:data/data/packagename/shared_prefs
可儲存數據類型:float、int、long、boolean、String、StringSet
SharedPreferences sp=context.getSharedPreferences(String name,int mode);//文件名、模式
MODE_PRIVATE只能被該文件讀寫
MODE_APPEND該文件內容可以追加
MODE_WORLD_READABLE可被其他文件讀取
MODE_WORLD_WRITEABLE可被其他應用寫入


常用方法(讀取):
sp.contains(String key) //判斷是否包含特定key的數據
sp.getAll() //獲取全部key/value鍵值對應
sp.getBoolean(String key,boolean defValue) //獲取key對應的Boolean值
(getInt||Float||Long||String||StringSet) //同理獲取
sp.edit() //獲取編輯器,返回Editor對象


常用方法(修改):
Editor np=sp.edit(); //得到編輯對象
np.putString("key","value"); //存入指定key的String||int||Float||Boolen||long值
np.putStringSet("key",Set<String> value) //存入指定key的set值
np.remove(key) //刪除指定的key所對應的數據
np.clear() //清除所有數據
np.commit() //編輯結束後提交




SQLite:數據庫數據位置位於data/data/packagename/database
SQLiteOpenHelper類 //用於創建數據庫和數據庫版本更新


常用方法:
SQLiteOpenHelper(Context context,String name,CursorFactory factory,int version)
分別代表:context、數據庫名稱、查詢的結果集、數據庫版本


onCreate(SQLiteDatabese db){ //創建數據庫調用該方法
SQLiteDatabese類--常用方法:
db.insert(String table,String nullColumnHack,ContentValues values)
分別代表:表名、列名、values參數集合。用於添加一條記錄
db.query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)
分別代表:表名、列名數據、查詢條件、查詢參數值、分組、聚合函數、排序。用於查詢
db.rawQuery(String sql,String[] selectionArgs)
分別代表:查詢sql語句、查詢條件
db.update(String table,ContentValues values,String whereClause,String[] whereArgs)
分別代表:代表想要更新數據的表名、代表想要更新的數據、滿足該whereClause子句的記錄將會被更新、用於爲whereArgs子句傳遞參數。用於修改特定數據
db.delete(String table,String whereClause,String[] whereArgs)
分別代表:table:代表想刪除數據的表名。
whereClause:滿足該whereClause子句的記錄將會被刪除。
whereArgs:用於爲whereArgs子句傳入參數。
例:
刪除person_inf表中所有人名以孫開頭的記錄
int result=db.delete("person_inf","person_name like ?",new String[]{"孫_"});

db.execSQL(String sql,Object[] bindArgs)
執行一條帶佔位符的SQL語句
db.close() //關閉數據庫
}


onUpgrade(SQLiteDatabese db,int oldVersion,int newVersion)
分別代表:數據庫名稱,舊版本,新版本  更新版本時調用


getReadable||WritableDatabase() //創建或打開一個只讀||讀寫的數據庫


Cursor接口(返回值,相當於ResultSet)
常用方法:
moveToNext() //移動光標到下一行
getInt(int columnIndex) //獲取列
getColumnIndex(String columnName) //返回列索引值,不存在則返回-1
getString(int columnIndex) //獲取指定列的字符串
moveToFirst() //移動光標到第一行
moveToLast() //移動光標到最後一行
moveToPrevious() //移動光標到上一行
moveToPosition(int position) //移動光標到指定位置
getCount() //返回Cursor中的行數
getPosition() //返回當前Cursor的位置
getColumnName(int columnIndex) //根據列的索引值獲取列的名稱
getColumnNames() //獲取Cursor所有列的名稱數組


sqlite3工具查看數據庫:
adb shell //掛載到linux的空間
cd  data/data/packagename/database //進入文件夾
sqlite3 databasename //操作的數據庫
select*from tablename //打開表




ListView適配器(Adapter)
BaseAdapter抽象方法
常用方法:getCount()//得到Item的總數
getItem(int position)//根據position得到Item對象
getItemId(int position)//根據position得到Item的ID
getView(int,View,ViewGroup)//視圖位置


SimpleAdapter只能適配Checkable、TextView、ImageView三種類型,繼承BaseAdapter
擁有BaseAdapter的全部方法,使用時直接在其構造方法中傳入參數即可
SimpleAdapter(Context,data,int,String[],int[])
Context用於佈局轉換爲View對象
data類似Map類的數據集合
int資源佈局的id
String[]Map集合裏面的key
int[]item佈局對應的控件id


ArrayAdapter繼承BaseAdapter,適用於TextView
擁有BaseAdapter的全部方法,使用時直接在其構造方法中傳入參數即可
ArrayAdapter(Context,int,int,T[])
Context用於佈局轉換爲View對象
int資源佈局的id(0,1)
int對應控件的id(R.id.a)
T[]需要適配的數組



ContentProvider:內容提供者,主要用於保存和檢索數據
ContentProvider抽象類//用於創建內容提供其他應用訪問


使用前清單文件註冊:
<provider
android:name="cn.itcast.db.PersonDBProvider"//繼承於ContentProvider類的全路徑名稱
android:authorities="cn.itcast.db.personprovider">//訪問路徑
可選參數配置:android:permission="mobile.permission.PROVIDER"
//其他應用訪問時必須 加上權限<user-permission android:name="mobile.permission.PROVIDER" />
android:readPermission屬性//使用後其他程序調用query()方法訪問數據時需要權限
android:writePermission屬性//使用後其他程序調用增刪改查更改數據時需要權限
</provider>


ContentProvider主要方法:onCreate()//創建時調用
delete(uri,selection,String[])//根據uri刪除指定條件下的數據
insert(uri,values)//根據傳入的uri插入數據
query(uri,string[],string,string[],string)//根據傳入的uri查詢指定條件下數據
update(uri,values,selection,string[])//根據uri更新指定條件下數據
getType(uri)//返回uri代表數據的MIME類型
uri是由:scheme、authorites、path組成。scheme部分是"content://"前綴||authorites代表"cn.itcast.db.personprovider||path代表資源person根據需要的不同,動態改變"
uri對應的方法:Uri.parse(String str)//將字符串變成路徑
UriMatcher用於匹配Uri的輔助類,主要的方法
UriMatcher(int code)//創建UriMatcher時調用,int通常指UriMatcher.NO_MATCH,不滿足返回-1
addURI(String authority,String path,int code)//前兩者分別代表Uri的半部分,後者代表返回碼
match(uri)//匹配uri與addURI方法傳入參數的code值,給予前面兩個,返回code值


ContentResolver:訪問內容提供者
Uri uri=Uri.parse("...");
ContentResolver r=context.getContentResolver();
Cursor c=r.query(uri,string[],string,string[],string);
String data=c.getString(int columnIndex)
c.close();


ContentObserver:內容觀察者
ContentObserver(Handler h)//構造方法,h可爲任意Handler對象
onChange(boolean selfChange)//當uri代表的數據發生修改時會調用該方法
使用該方法之前必須調用ContentResolver的notifyChange()方法,在ContentProvider中insert()update()delete()方法中
getContentResolver().notifyChange(Uri uri,ContentObserver cob);//分別uri、和觀察者,不指定觀察者可寫null




BroadcastReceiver廣播接收者
打電話時廣播:
<receiver android:name="cn.itcast.MyBroadcastReceiver">//監聽類路徑
<intent-filter android:priority="20">//優先級,值越大,接收優先級越高(-1000~1000)之間
<action android:name="android.intent.action.NEW_OUTGOING.CALL">//受到監視的廣播,此處是打電話廣播
</intent-filter>
</receiver>
權限:<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />


短信接收廣播:
<receiver android:name="cn.itcast.MyBroadcastReceiver">//監聽類路徑
<intent-filter android:priority="20">//優先級,值越大,接收優先級越高(-1000~1000)之間
<action android:name="android.provider.Telephony.SMS_RECEIVED">//受到監視的廣播,此處是短信接收廣播
</intent-filter>
</receiver>
權限:<uses-permission android:name="android.permission.RECEIVE_SMS" />


開機廣播:
<receiver android:name="cn.itcast.MyBroadcastReceiver">//監聽類路徑
<intent-filter android:priority="20">//優先級,值越大,接收優先級越高(-1000~1000)之間
<action android:name="android.intent.action.BOOT_COMPLETED">//受到監視的廣播,此處是短信接收廣播
</intent-filter>
</receiver>
權限:<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


繼承BroadcastReceiver類,重寫onReceive方法。
onReceive(Context c,Intent i)//當監聽到廣播事件時,調用該方法
註冊常駐廣播:當應用程序關閉後,接收到其他的應用發出的廣播,該程序就會自動重新啓動
<receiver android:name="cn.itcast.MyBroadcastReceiver">//上述類路徑
<intent-filter android:priority="20">//優先級,值越大,接收優先級越高(-1000~1000)之間
<action android:name="android.provider.Telephony.SMS_RECEIVED">//受到監視的廣播,此處是短信接收廣播
</intent-filter>
</receiver>
註冊非常駐廣播:當應用程序關閉後,就不再起作用
MyBroadcastReceiver r=new MyBroadcastReceiver();//上述類
String a="android.provider.Telephony.SMS_RECEIVED";//受到監視的廣播,此處是短信接收廣播
IntentFilter intentFilter=new IntentFilter(action);//設置要過濾的廣播
registerReceiver(r,intentFilter);//註冊廣播
註冊非常駐廣播需要解除廣播,例如在onCreate()中註冊廣播,需要在onDestory()中解除廣播
unrgisterReceiver(r);


自定義廣播:
Intent i=new Intent();
i.setAction("www.itcast.cn");//定義廣播的事件類型
sendBroadcast(i);//發送廣播
接收廣播可接收數據
<receiver android:name="cn.itcast.MyBroadcastReceiver">//廣播接收者,可添加多個
<intent-filter>
<action android:name="www.itcast.cn">
</intent-filter>
</receiver>
onReceive(c,i){
String n=i.getAction;
}


廣播類型:無序廣播和有序廣播,前者效率高,但無法被攔截,後者根據優先級接收廣播,同優先級先安裝應用優先結束
有序廣播攔截廣播調用方法abortBroadcast()即可使廣播不再傳播
sendOrderedBroadcast(i,null);//發送有序廣播。intent,指定接收者,可強制接收廣播,哪怕高級攔截了廣播,一樣可以接受到廣播,可指定多個,(i,null,activ,01,02...);


利用廣播開機自啓:第一步,監聽開機事件,自android3.0後,必須安裝打開過的android軟件纔可以開機自啓。
第二步,在監聽方法中執行Intent i=new Intent(context,主函數.class);
i.setFlags(intent.FLAG_ACTIVITY_NEW_TASK);//指定Activity運行在任務棧中
context.startActivity(i);//啓動該應用


一. intent.setFlags()方法中的參數值含義:
1.FLAG_ACTIVITY_CLEAR_TOP:跳轉到的activity若已在棧中存在,則將其上的activity都銷掉。


2.FLAG_ACTIVITY_NEW_TASK:跳轉到的activity根據情況,可能壓在一個新建的棧中。


3.FLAG_ACTIVITY_NO_HISTORY:跳轉到的activity不壓在棧中。


4.FLAG_ACTIVITY_SINGLE_TOP:目標activity已在棧頂則跳轉過去,不在棧頂則在棧頂新建activity。


二.intent.setFlags()方法中參數的用例:
很多人使用startActivity時候,會碰到如下的異常:
Caused by: Android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
都知道,Context中有一個startActivity方法,Activity繼承自Context,重載了startActivity方法。如果使用Activity的startActivity方法,不會有任何限制,而如果使用Context的startActivity方法的話,就需要開啓一個新的task,遇到上面那個異常的,都是因爲使用了Context的startActivity方法。解決辦法是:Java代碼中加一個flag,即intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。這樣就可以在新的task裏面啓動這個Activity了。




服務:能長期在後臺運行且不提供任何界面
清單文件註冊:(位於"</application>"之前)
<service android:name="cn.itcast.servicetest.myservice" />
啓動方式:(服務不能主動啓動,只能被調用)兩種Context.startService()、Context.bindService()




Context.startService():使用起來相對方便,但不能進行數據交互
其他組件調用startService()方法→onCreate()→onStartCommand()→stopSelf()或者stopService()→onDestroy();
創建 第一次啓動 運行中       自己調用關閉 其他組件調用關閉 銷燬


例:Intent i=new Intent(this,myservice.class);
Context.startService(i); //開啓服務
Context.stopService(i); //關閉服務
創建服務:public class myservice extends Service{ //繼承Service抽象類
public IBinder onBind(Intent arg0){ //重寫唯一的抽象方法
return null;
}
}






Context.bindService():可實現數據交互
其他組件調用bindService()方法→onCreate()→onBind()→unBindService()→onDestroy();
創建       第一次啓動    運行中   客戶通過此方法關閉(可對應多個客戶,當全部客戶都斷開連接,此服務銷燬) 銷燬


例:Intent i=new Intent(this,myservice.class);
創建服務:public class myservice extends Service{ //繼承Service抽象類
public IBinder onBind(Intent arg0){ //重寫唯一的抽象方法,綁定服務
return new MyBinder();
}
class MyBinder extends Binder{
public void callMethodInService(){
...
}
}
public void onCreate(){super.onCreate();} //創建服務
public void boolean onUnbind(intent i){return super.onUnbind(i);}//解綁服務
}
鏈接服務:public class MyConn implements ServiceConnection{ //接入接口
public void onServiceConnected(ComponentName name,IBinder service){//當服務成功綁定時調用的方法
MyBinder myBinder=(MyBinder) service;//通過service傳遞參數
}
public void onServiceDisconnected(ComponentName name){ //當服務失去連接時調用的方法
}
}


MyConn myconn=new MyConn();
Context.bindService(intent,myconn,BIND_AUTO_CREATE); //intent,鏈接對象,flag表示沒有就重新創建
Context.unbindService(myconn); //解綁服務




遠程服務通訊:通過AIDL實現不同應用之間的綁定服務
第一步:創建AIDL文件
package 包名
interface 文件名{需要跨軟件調用的方法...}
第二步:創建Service服務器端
public class myservice extends Service{
public IBinder onBind(Intent arg0){ //重寫唯一的抽象方法,綁定服務
return null;
}
...其他方法任意
}
第三步:清單文件中配置
        <service android:name=".myservice"> //配置服務器的java文件
            <intent-filter>
                <action android:name="com.yu.IMyService"/> //調用時用的action
            </intent-filter>
        </service>
第四步:客戶端調用
複製alid文件至對應的包中,conn=new MyConn();
bindService(new Intent("com.yu.IMyService"), conn, BIND_AUTO_CREATE); //綁定服務
unbindService(conn); //解綁服務
private IService iService; //alid文件
iService.方法名() //調用其它應用方法
private class MyConn implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
iService=IService.Stub.asInterface(service); //鏈接成功調用
}
@Override
public void onServiceDisconnected(ComponentName name) { //當服務失去連接時調用的方法
// TODO Auto-generated method stub
}
}




網絡編程:UI線程不能訪問網絡,子線程不能根系UI界面。
Handler機制包括四個關鍵對象Message、Handler、MessageQueue、Looper
Message:可用於線程之間傳遞消息,不同的線程之間交換數據.
what、obj分別可攜帶整形數據和Object對象


Handler:用於發送消息【sendMessage()】和處理消息,最後會傳遞到Handler對象的handlerMessage()方法中


MessageQueue:消息隊列,主要用來存放通過Handle發送的消息,每個線程中只會有一個MessageQueue對象


Looper:每個線程中MessageQueue的管家,調用Looper的loop()方法後將會無限循環,每當發現MessageQueue對象存在消息,就將他取出,並傳遞到Handler對象的handlerMessage()中,每個線程中只會有一個Looper對象,主線程中自帶loop()方法,自動循環,子線程需要調用Looper.loop方法來開啓消息循環。


Handler→發送消息→MessageQueue→利用Message攜帶消息發送至MessageQueue中→Looper→取出隊列的消息處理→發送至Handler的handlerMessage()方法中


AsyncTask抽象類,異步處理機制,可從子線程切換到主線程。
class Down extends AsyncTask<Void,Integer,Boolean> //Params傳入的參數,給予後臺任務使用,Porgress進度顯示進度單位,Result返回結果類型
主要方法:onPreExcute()後臺任務執行之前調用
doInBackgroud(Params...)子線程中運行,可調用publishProgress(Porgress...)來更新UI
onProgressUpdate(Params...)如果在上述方法中調用了publishProgress(Porgress...)更新UI,本方法就會被調用
onPostExcute(Result)當doInBackgroud方法完畢時,並通過return返回參數,將傳遞到本方法當中,提示任務完成情況
asyncTask.execute("http://www.google.com");//可以通過此處傳參數給AsyncTask,execute方法只能在UI線程裏使用




HttpURLConnection訪問網絡
HttpURLConnection的基本用法:
<user-permission android:name="android.permission.INTERNET" /> //清單位置權限,任何方式訪問網絡都是這個權限
URL u=new URL("http://anlemusic.cn"); //設置URL
HttpURLConnection c=(HttpURLConnection)url.openConnection(); //根據URL發送HTTP請求
c.setRequestMethod("GET"); //設置請求方式
c.setConnectTimeout(5000); //設置超時時間
c.setRequestProperty("User-Agent","..."); //設置請求頭User-Agent瀏覽器版本
c.getResponseCode(); //返回服務器返回碼
InputStream i=c.getInputStream(); //獲取服務器返回的輸入流
讀取流信息,獲取服務器返回數據
c.disconnect(); //關閉http鏈接




HttpClient訪問網絡
主要方法:
DefaultHttpClient() //用於創建HttpClient對象
HttpGet(URL) //創建GET方式請求創建該類實例
HttpPost() //使用POST方式請求創建該實例
setParams(params) //HttpGet、HttpPost都具有此方法,用於設置請求參數
setEntity() //HttpPost可用設置請求參數
HttpClient.execute() //訪問網絡,獲取HttpResponse對象
NameValuePair //關聯參數的KEY
BasicNameValuePair //以Key,Value的形式存放參數的類
UrlEncodedFormEntity //將提交給服務器參數進行編碼的類
HttpResponse //封裝了服務器返回信息的類
HttpEntity //封裝了服務返回數據的類


HttpClient http=new DefaultHttpClient(); //創建HttpClient對象
HttpPost httpPost=new HttpPost("網址"); //設置請求方式
List<NameValuePair> params=new ArrayList<NameValuePair>(); //創建一個NameValuePair的集合
params.add(new BasicNameValuePair("username","admin")); //添加參數
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(params,"utf-8"); //給參數設置編碼
httpPost.setEntity(entity); //設置參數
HttpResponse response=http.execute(httpPost); //獲取HttpResponse對象
int code=response.getStatusLine().getStatusCode(); //獲取狀態碼
if(code==200){ //訪問成功
HttpEntity Entity=response.getEntity(); //獲取httpEntity的實例
String re=EntityUtils.toString(Entity,utf-8); //設置編碼格式
}




AsyncHttpClient訪問網絡 完美解決了UI線程不能訪問網絡
使用之前需要導入對應的夾包,本文件夾就有...此方式主要是對HttpClient再次包裝.
AsyncHttpClient //用來訪問網絡的類
RequestParams //用於添加參數的類
AsyncHttpResponseHandle //訪問網絡後回調的接口


AsyncHttpClient client=new AsyncHttpClient(); //創建AsyncHttpClient實例
String path="訪問的URL"; //設置拼接的URL
client.get(path,new AsyncHttpResponseHandle(){ //get的方式請求網絡
public void onSuccess(String content){ //訪問網絡成功
super.onSuccess(content);
Toast.makeText(this,"請求成功"+content,0).show();
}
public void onFailure(Throwable error,String content){ //訪問網絡失敗
super.onFailure(error,content);
Toast.makeText(this,"請求失敗"+content,0).show();
}
});


AsyncHttpClient client=new AsyncHttpClient(); //創建AsyncHttpClient實例
String url="訪問的URL"; //設置訪問地址
RequestParams params=new RequestParams(); //用於添加參數的類
client.post(url,params,new AsyncHttpResponseHandle(){ //post的方式請求網絡
public void onSuccess(int statusCode,Header[] headers,byte[] responseBody){ //訪問網絡成功
super.onSuccess(statusCode,headers,responseBody);
Toast.makeText(this,"請求成功"+new String(responseBody),0).show();
}
public void onFailure(Throwable error,String content){ //訪問網絡失敗
super.onFailure(error,content);
Toast.makeText(this,"請求失敗"+content,0).show();
}
});




SmartImageView控件,使用之前需要導入對應的夾包,本文件夾就有...此方法主要解決加載圖片慢的問題.
<com.loopj.android.image.SmartImageView
android:layout_weight="1000"
android:id="@+id/id"
android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


java文件中:SmartImageView siv=(SmartImageView)findViewById(R.id.id);
siv.setImageUrl("指定地址的圖片",R.drawable.ic_error,R.drawable.ing);//網絡圖片沒找到時顯示的圖片,正在加載的圖片




多線程下載:首先獲得服務器資源文件大小,然後再在本地創建一個大小與服務器一樣的文件,接着在客戶端開啓若干個線程去下載服務器資源,每個線程下載自己對應的模塊.
long l=conn.getContentLength(); //獲取文件大小
RandomAccessFile r=new RandomAccessFile("文件名","類型"); //隨機文件名+類型
r.setLength(l); //設置本地文件大小
threadCount=3; //設置線程數量
long blocksize=l/threadCount; //設置每個線程下載區塊的大小
for(int id=1;id<=threadCount;id++){
long starPos=(id-1)*blocksize; //從starPos字節開始下載
long endPos=id*blocksize-1; //知道endPos字節結束
if(id==threadCount){
endPos=l;
new Down(starPos,endPos,id,path).start(); //開始下載
}
}


class Down extends Thread{
private long starPos;...
Down(long starPos,long endPos,long id,String path){
super();
this.starPos = starPos;....
}
public void run(){
conn.setRequestProperty("Range","bytes="+starPos+"-"+endPos); //請求部分數據
InputStream is=conn.getInputStream();
RandomAccessFile r=new RandomAccessFile("文件名","類型");
r.seek(startPos);
int len=0;
byte[] b=new byte[1024];
while((len=is.read(buffer))!=-1){
r.write(buffer,0,len);
}
is.close();
r.close();
}
}




傳感器andrid.hardware.Sensor:
<uses-permission android:name="android.permission.VIBRATE" /> //震動
<uses-permission android:name="android.hardware.sensor.accelerometer" /> //加速度傳感器


傳感器信息的方法:
getName() //傳感器名稱
getVersion() //傳感器版本
getvendor() //傳感器製造商的名稱
getType() //傳感器類型
getPower() //傳感器功率


傳感器類型常量 內部整數值 中文名稱
Sensor.TYPE_ACCELEROMETER 1 加速度傳感器
Sensor.TYPE_MAGNETIC_FIELD 2 磁力傳感器
Sensor.TYPE_ORIENTATION 3 方向傳感器
Sensor.TYPE_GYROSCOPE 4 陀螺儀傳感器
Sensor.TYPE_LIGHT 5 環境光照傳感器
Sensor.TYPE_PRESSURE 6 壓力傳感器
Sensor.TYPE_TEMPERATURE 7 溫度傳感器
Sensor.TYPE_PROXIMITY 8 距離傳感器
Sensor.TYPE_GRAVITY 9 重力傳感器
Sensor.TYPE_LINEAR_ACCELERATION 10 線性加速度傳感器
Sensor.TYPE_ROTATION_VECTOR 11 旋轉矢量
Sensor.TYPE_RELATIVE_HUMIDITY 12 溼度傳感器
Sensor.TYPE_AMBIENT_TEMPERATURE 13 溫度傳感器(4.0之前用Sensor.TYPE_TEMPERATURE)


獲取所有傳感器:
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE); //獲取傳感器管理器
List<Sensor> allSensors=sm.getSensorList(Sensor.TYPE_ALL); //從傳感器管理器中獲取全部傳感器列表
allSensors.size();//顯示一共有多少個傳感器
for(Sensor s:allSensors){
s.getName();//列出傳感器名稱
}


獲取指定傳感器:
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
Sensor sensor=sm.getDefaultSensor(Sensor.TYPE_GRAVITY);//使用getDefaultSensor(int type)方法獲取
if(sensor!=null){
//重力傳感器存在
sensor.getName();
//獲取傳感器的供應商
sensor.getvendor();
}else{
//重力傳感器不存在
}




傳感器註冊監聽事件:
sm.registerListener(SensorEventListener listerner,Sensor sensor,int rate);
listerner:監聽接口擁有兩個方法,分別是:onSensorChanged(SensorEvent event)和onAccuracyChanged(Sensor sensor,int rate);前者在傳感器發生變化時調用,後者在精確度不準確時調用。
Sensor sensor:表示傳感器對象
int rate:表示傳感器數據採樣率:10ms、20ms、60ms、200ms,分別對應0,1,2,3,也可以用SensorManager.SENSOR_DELAY_FASTEST||GAME||UI||NORMAL


註銷傳感器:
protected void onDestroy(){
 super.onDestroy();
 sm.unregisterListener(listener);
 listener=null;


}




Fragment:與Activity類似,一個Activity可以包含多個Fragment
Fragment生命週期:
添加Fragment→onAttach()→onCreate()→onCreateView()→onActivityCreated()→onStart()→onResume()→Fragment已激活→點擊返回→onPause()→onStop()→onDestroyView()→onDestroy()→onDetach()→Fragment被銷燬
onAttach():當Fragment和Activity建立關聯時調用
onCreateView():爲Fragment創建視圖時調用
onActivityCreate():確保與Fragment相關聯的Activity已經創建完成時調用
onDestroyView():Fragment視圖被移除時調用
onDetach():Fragment與Activity解除關聯的時候調用


public class NewFragment extends Fragment{
 public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
View v=inflater.inflate(R.layout.fragment,container,false);
return v;
}
}


<fragment
android:name="包.類"
android:id="@+id/id"
android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


NewFragment f=new NewFragment(); //實例化Fragment對象
FragmentManager fm=getFragmentManager(); //獲取FragmentManager實例
FragmentTransaction begin=fm.beginTransaction(); //獲取FragmentTransaction實例
begin.add(R.id.id); //添加一個Fragment
begin.commit(); //提交




Fragment與Activity通訊
在佈局中定義SettingListFragment對象
<SettingListFragment
android:id="@+id/id"
android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
//activity調用fragment
SettingListFragment f=(SettingListFragment)getFragmentManager().findFragmentById(R.id.id);


在Fragment中獲取Activity實例
MainActivity activity=(MainActivity)getActivity();//調用getActivity方法得到Context對象


Fragment與Fragment對象之間互相交流就是依靠Activity實例對象調用


附一:MUSIC
MediaPlayer常用方法:
setAudioStreamType() //指定音頻文件類型
setDataSource() //設置要播放的音頻文件位置
prepare() //播放之前準備工作
start() //開始播放
pause() //暫停播放
reset() //將其對象重置到剛剛創建的狀態
seekTo() //從指定的位置開始播放音頻 重新播放可m.seekTo(0);m.start();
stop() //停止播放音頻
release() //釋放資源
isPlaying() //判斷當前是否在播放
getDuration() //獲取音樂文件時長
getCurrentPosition() //獲取當前播放音頻位置
音樂播放流程:
m=new MediaPlayer(); //創建MediaPlayer播放器
m.setAudioStreamType(AudioManager.STREAM_MUSIC); //指定參數類型AudioManager.STREAM_MUSIC||RING||ALARM||NOTIFICTION音樂、響鈴、鬧鐘、提示音
m.setDataSource(path); //指定路徑
m.prepare(); //準備播放
mediaplayer.setOnPreparedListener(new OnPreparedListener(){ //檢測掃描預處理
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaplayer.start(); //開始播放
}
});


音樂源:
m.create(this,R.raw.xxx); //app內部
m.setDataSource("mnt/sdcard/1.mp3") //SD卡中文件
m.setDataSource("http://www.anlemusic.cn/2.mp3") //網絡音頻


網絡音樂播放不同:m.prepareAsync(); //準備工作
m.setOnPreparedListener(new OnPreparedListener){ //檢測掃描預處理
public void onPrepared(MediaPlayer player){
m.start(); //開始播放
}
}




SoundPool播放音頻
SoundPool sound=new SoundPool(int maxStreams,int streamType.int srcQuality);//同時播放流的最大數量,流的類型AudioManager.STREAM_MUSIC,採樣率轉換質量,當前無效果可用0
Map<Integer,Integer> soundMap=new HashMap<Integer,Integer>(); //音樂Map
soundMap.put(0,sound.load(this,R.raw.dingdong,1)); //load()方法添加音樂文件
soundMap.put(0,sound.load(this,R.raw.ding,1));
sound.setOnLoadCompleteListener(new OnLoadCompleteListener(){
public void onLoadComplete(SoundPool sound,int sampleId,int status){
play(soundMap.get(0),(float)1,(float)1,0,0,(float)1.2); //id,左音量,右音量,優先級,loop循環次數,速率最低0.5·最高2·正常1.0
play(soundMap.get(1),(float)1,(float)1,0,0,(float)1.2);
}
});




附二:Video
VideoView視頻播放




SurfaceView視頻播放
setVideoPath() //設置要播放的視頻文件位置
start() //開始或繼續播放視頻
pause() //暫停播放視頻
resume() //視頻重頭開始播放
seekTo() //從指定位置開始播放視頻
isPlaying() //判斷當前是否正在播放視頻
getDuration() //獲取載入的視頻文件的時長
stopPlayback() //停止播放視頻


VideoView v=(VideoView)findViewById(R.id.video); //找到控件
v.setVideoPath("mnt/sdcard/apple.avi"); //加載視頻
//v.setVideoURI("http://www.xxx.avi"); //網絡視頻加載
v.start(); //播放視頻


視頻控制器:
MediaController controller=new MediaController(context);
v.setMediaController(controller); //爲VideoView綁定控制器


MediaPlayer和SurfaceView結合播放視頻,前者用於播放聲音,後者利用兩個線程互相配合,完成動畫


<SurfaceView
android:id="@+id/sv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>


SurfaceView view=(SurfaceView)findViewById(R.id.sv);
SurfaceHolder holder=view.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new Callback(){
 public void surfaceDestroyed(SurfaceHolder holder){
//銷燬SurfaceHolder觸碰事件
}
 public void surfaceCareated(SurfaceHolder holder){
//創建SurfaceHolder觸碰事件
}
 public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){
//大小發生變化時
}
});
MediaPlayer mediaplayer=new MediaPlayer();
mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaplayer.setDataSource("path");
mediaplayer.prepareAsync();
mediaplayer.start();


CountDownTimer cdt=new CountDownTimer((3000,1000){
 public void onTick(long millisUntilFinished){
每隔1000ms執行一次
}
 public void onFinish(){
3000ms之後執行
}
});


RelativeLayout rl=(RelativeLayout)findViewById(R.id.rl);
rl.setVisibility(View.INVISIBLE); //隱藏該控件
rl.setVisibility(View.VISIBLE); //顯示該控件
附三:IMAGE
Bitmap類的常用方法:用於圖像處理.
createBitmap(int width,int height,Config config) //創建位圖,分別爲寬度,高度,圖片的配置信息
createBitmap(int colors[],int offset,int stride,int width,int height,Config config)
//使用顏色數組,創建一個指定寬高的位圖,顏色數組個數爲width*height,圖片的配置信息
createBitmap(Bitmap src) //使用源位圖創建一個新的Bitmap對象
createBitmap(Bitmap source,int x,int y,int width,int height) //從源位圖的指定座標開始挖去width寬的,height高的Bitmap對象
createBitmap(Bitmap source,int x,int y,int width,int height,Matrix m,boolean filter)
//從源位圖的指定座標開始挖取width寬的,height高的Bitmap對象,並按照Matrix規則進行變換
isRecycled() //判斷Bitmap對象是否被收回
recycle() //回收Bitmap對象


Config c=Config.ARGB_4444; //config表示每像素多少字節,也就是畫質,ARGB_4444兩個字節、ARGB_8888四個字節
Bitmap b=Bitmap.createBitmap(200, 200, c);




BitmapFactory類常用方法:從不同數據源中解析,創建Bitmap對象
decodeFile(String pathName) //從指定文件中解析,創建Bitmap對象
decodeStream(InputStream is) //從輸入流中解析,創建Bitmap對象
decodeResource(Resources res,int id) //根據給定的資源id,從指定資源中解析,創建Bitmap對象


Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);




Paint類
Paint() //創建一個Paint對象
Paint(int flags) //創建Paint對象,指定屬性
setARGB(int a,int r,int g,int b) //設置顏色,透明度,RGB,範圍都是(0~255)
setColor(int color) //設置顏色
setAlpha(int a) //設置透明度
setAntiAlias(boolean aa) //設置是否使用抗鋸齒功能,使用會使繪圖速度變慢
setDither(boolean dither) //指定圖像是否抖動處理,圖像會更平滑,飽滿,清晰
setShadowLayer(float radius,float dx,float dy,int color) //設置陰影,陰影角度,陰影在x軸y軸的距離,color陰影顏色
setTextAlign(Align align) //設置繪製文本時的文字對齊方式Align.CENTER、LEFT、RIGHT
setTextSize(float textSize) //設置繪製文本時字體大小
setFakeBoldText(boolean fakeBoldText) //設置文字是否爲粗體
setXfermode(Xfermode xfermode) //設置圖形重疊時處理方式,合併或者交集,並集,製作橡皮擦擦除效果


Paint p=new Paint();
p.setColor(Color.RED);
p.setShadowLayer(2,3,3,Color.GRAY)




Canvas類
使用之前需要繼承View類,並且重寫onDraw(Canvas canvas)方法
drawRect(Rect r,Paint pain) //使用畫筆畫出指定的矩形
drawOval(RectF oval,Paint pain) //使用畫筆畫出指定的橢圓
drawCircle(float cx,float cy,float radius,Paint paint) //使用畫筆畫出指定的半徑的園
drawLine(float startX,float startY,float stopX,float stopY,Paint paint)//畫直線
drawRoundRect(RectF rect,float rx,float ry,Paint paint) //畫圓角矩形

class pictures extends View{


public pictures(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint p=new Paint();
p.setColor(TRIM_MEMORY_BACKGROUND);
p.setShadowLayer(2, 3, 3, Color.BLUE);
Rect r=new Rect(40,40,200,100);
canvas.drawRect(r, p);
}
}


<com.example.xy.pictures
android:id="@+id/id"
android:layout_width="wrap_content"
        android:layout_height="wrap_content"
/>




Matrix類主要方法:用於添加特效
Matrix() //創建一個唯一的Matrix類
setRotate(float degress) //將Matrix對象圍繞(0,0)旋轉degress度
setRotate(float degress,float x,float y) //將Matrix對象圍繞(x,y)旋轉degress度
setScale(float sx,float sy) //對Matrix對象進行縮放,XY軸分別縮放比例
setScale(float sx,float sy,float x,float y) //對Matrix對象進行縮放,XY軸分別縮放比例,以(x,y)爲軸心
setSkew(float sx,float sy) //讓Matrix對象傾斜,X軸,Y軸,分別傾斜kx,ky
setSkew(float sx,float sy,float x,float y) //讓Matrix對象傾斜,X軸,Y軸,分別傾斜kx,ky,以(x,y)爲軸心
setTranslate(float dx,float dy) //讓Matrix對象平移,(dx,dy)爲Matrix爲平移後的座標


matrix m=new Matrix();
canvas.drawBitmap(bitmap,m,paint);


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