在之前的學習過程中已經將Android學習完了,但是在后面將近一年的時間里都沒有進行過Android開發,所以對Android的所有的知識點又有點忘記了,因此才會繼續的學習Android,做出這個學習筆記。另外:由於在暑假的時候要開發Android項目,所以對於這些Android知識點也都要熟練的掌握。
目錄
在實際開發中,開發android軟件的過程需要不斷地進行測試。而使用Junit測試框架,側是正規Android開發的必用技術,在Junit中可以得到組件,可以模擬發送事件和檢測程序處理的正確性。
首先建立一個新的Android項目,這里我命名為:junit,然后編寫AndroidManifest.xml文件,在里面添加uses-library和instrumentation兩個屬性,代碼如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="lq.wangzhen.junit" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <instrumentation 8 android:name="android.test.InstrumentationTestRunner" 9 android:label="Tests for My App" 10 android:targetPackage="lq.wangzhen.junit" /> 11 12 <uses-sdk 13 android:minSdkVersion="8" 14 android:targetSdkVersion="8" /> 15 16 <application 17 android:allowBackup="true" 18 android:icon="@drawable/ic_launcher" 19 android:label="@string/app_name" 20 android:theme="@style/AppTheme" > 21 <uses-library android:name="android.test.runner" /> 22 23 <activity 24 android:name="lq.wangzhen.junit.DemoActivity" 25 android:label="@string/app_name" > 26 <intent-filter> 27 <action android:name="android.intent.action.MAIN" /> 28 29 <category android:name="android.intent.category.LAUNCHER" /> 30 </intent-filter> 31 </activity> 32 </application> 33 34 </manifest>
其中在instrumentation中配置的targetPackage為測試類所在的包,我這里的包名為:lq.wangzhen.junit
編寫完以上的代碼以后,則可以在lq.wangzhen.junit包中定義一個類,這個類中包含一個Add方法,然后我們進行此方法的測試工作。代碼如下:
Services.java
1 package lq.wangzhen.junit; 2 3 public class Service { 4 5 /** 6 * 提供一個方法,可以接收兩個整型數據 7 * @param x 8 * @param y 9 * @return 10 */ 11 public static int add(int x,int y){ 12 return x+y; 13 } 14 }
下面編寫測試類,此類命名為:TestAddService.java,此類必須要集成AndroidTestCase才能夠作為測試類進行使用,代碼如下:
1 package lq.wangzhen.junit; 2 3 import junit.framework.Assert; 4 import android.test.AndroidTestCase; 5 6 public class TestAddService extends AndroidTestCase { 7 8 public void testAdd(){ 9 int result = Service.add(3, 5); 10 Assert.assertEquals(8, result); 11 } 12 }
以上就是一個簡單的Android測試過程
完成完以上的測試功能后,下面我們來完成一個簡單的用戶登陸功能,現在要求用戶輸入用戶名和密碼,並選擇是否保存用戶名和密碼,如果保存用戶名和密碼的話,我們要在ROM進行保存,然后在用戶下次打開此軟件時會自動的從文件中提取出對應的用戶名和密碼,填入到登陸框中,在本節中就先對界面進行一下設計,界面設計的xml文件如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <TextView 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="@string/username" /> 11 <EditText 12 android:id="@+id/et_username" 13 android:layout_width="fill_parent" 14 android:layout_height="wrap_content" 15 android:hint="@string/username" 16 /> 17 18 <TextView 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:text="@string/password" /> 22 <EditText 23 android:id="@+id/et_password" 24 android:layout_width="fill_parent" 25 android:layout_height="wrap_content" 26 android:hint="@string/password" 27 android:inputType="textPassword" 28 /> 29 30 31 <RelativeLayout 32 android:layout_width="fill_parent" 33 android:layout_height="wrap_content"> 34 <Button 35 android:id="@+id/button" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content" 38 android:text="@string/login" 39 android:layout_alignParentLeft="true"/> 40 <CheckBox 41 android:id="@+id/cb_remember" 42 android:layout_width="wrap_content" 43 android:layout_height="wrap_content" 44 android:text="@string/remember_password" 45 android:layout_alignParentRight="true"/> 46 </RelativeLayout> 47 48 </LinearLayout>
下面開始編寫MainActivity.java文件,代碼如下:
1 package lq.wangzhen.file; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.text.TextUtils; 6 import android.util.Log; 7 import android.view.View; 8 import android.view.View.OnClickListener; 9 import android.widget.Button; 10 import android.widget.CheckBox; 11 import android.widget.EditText; 12 import android.widget.Toast; 13 14 public class MainActivity extends Activity implements OnClickListener { 15 16 private static final String TAG = "MainActivity"; 17 private EditText et_username; 18 private EditText et_password; 19 private Button button; 20 private CheckBox cb_remember; 21 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.activity_main); 26 27 et_username = (EditText) this.findViewById(R.id.et_username); 28 et_password = (EditText) this.findViewById(R.id.et_password); 29 button = (Button) this.findViewById(R.id.button); 30 cb_remember = (CheckBox) this.findViewById(R.id.cb_remember); 31 32 33 button.setOnClickListener(this); 34 35 } 36 37 @Override 38 public void onClick(View v) { 39 // TODO Auto-generated method stub 40 switch (v.getId()) { 41 case R.id.button: 42 43 String username = et_username.getText().toString().trim(); 44 String password = et_password.getText().toString().trim(); 45 46 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ 47 Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show(); 48 return; 49 } 50 if(cb_remember.isChecked()){ 51 Log.i(TAG, "保存用戶名和密碼,"+username+":"+password); 52 }else{ 53 Log.i(TAG, "沒有保存用戶名和密碼,"+username+":"+password); 54 } 55 break; 56 } 57 } 58 59 60 }
以上程序所使用的strings.xml文件的內容如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <string name="app_name">file</string> 5 <string name="hello_world">Hello world!</string> 6 <string name="menu_settings">Settings</string> 7 8 <string name="username">用戶名</string> 9 <string name="password">密碼</string> 10 <string name="login">登陸</string> 11 <string name="remember_password">記住密碼</string> 12 <string name="error">用戶名和密碼不能為空</string> 13 14 </resources>
下面對以上的程序進行修改,加入可以將用戶名和代碼保存到文件中的功能,首先新建立一個Service文件,用來操作文件的保存,代碼如下:
1 package lq.wangzhen.service; 2 3 import java.io.FileOutputStream; 4 5 import android.content.Context; 6 7 public class FileService { 8 9 10 private Context context; 11 12 public FileService(Context context){ 13 this.context = context; 14 } 15 /** 16 * 把用戶名和密碼保存到手機ROM 17 * @param password 輸入要保存的密碼 18 * @param username 要保存的用戶名 19 * @param filename 保存到哪個文件 20 * @return 21 */ 22 public boolean saveToRom(String password,String username,String filename) throws Exception{ 23 //以私有的方式打開一個文件 24 FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE); 25 String result = username+":"+password; 26 fos.write(result.getBytes()); 27 fos.flush(); 28 fos.close(); 29 return true; 30 } 31 }
修改MainActivity.java文件,代碼如下:
1 package lq.wangzhen.file; 2 3 import lq.wangzhen.service.FileService; 4 import android.app.Activity; 5 import android.os.Bundle; 6 import android.text.TextUtils; 7 import android.util.Log; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.Button; 11 import android.widget.CheckBox; 12 import android.widget.EditText; 13 import android.widget.Toast; 14 15 public class MainActivity extends Activity implements OnClickListener { 16 17 private static final String TAG = "MainActivity"; 18 private EditText et_username; 19 private EditText et_password; 20 private Button button; 21 private CheckBox cb_remember; 22 private FileService fileService; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 29 et_username = (EditText) this.findViewById(R.id.et_username); 30 et_password = (EditText) this.findViewById(R.id.et_password); 31 button = (Button) this.findViewById(R.id.button); 32 cb_remember = (CheckBox) this.findViewById(R.id.cb_remember); 33 34 35 button.setOnClickListener(this); 36 37 //初始化文件服務 38 fileService = new FileService(this); 39 40 } 41 42 @Override 43 public void onClick(View v) { 44 // TODO Auto-generated method stub 45 switch (v.getId()) { 46 case R.id.button: 47 48 String username = et_username.getText().toString().trim(); 49 String password = et_password.getText().toString().trim(); 50 51 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ 52 Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show(); 53 return; 54 } 55 if(cb_remember.isChecked()){ 56 Log.i(TAG, "保存用戶名和密碼,"+username+":"+password); 57 try { 58 boolean result = fileService.saveToRom(password, username, "private.txt"); 59 if(result){ 60 Toast.makeText(getApplicationContext(), R.string.success, Toast.LENGTH_SHORT).show(); 61 }else{ 62 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 63 } 64 } catch (Exception e) { 65 // TODO Auto-generated catch block 66 e.printStackTrace(); 67 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 68 } 69 } 70 break; 71 } 72 } 73 74 75 }
在strings.xml文件中添加以下的內容:
1 <string name="success">保存成功</string> 2 <string name="failed">保存失敗</string>
運行程序,即可保存成功,保存的文件默認的保存在data/data/lq.wangzhen.file/files文件夾中,其中lq.wangzhen.file表示Activity所在的包名。下面在此程序的基礎上加入可以從文件中讀取用戶名和密碼的功能,首先在FileService.java文件中添加以下的一個方法,用來從ROM中讀取文件內容。
1 public Map<String,String> getUserInfo(String filename) throws Exception{ 2 File file = new File("data/data/lq.wangzhen.file/files/"+filename); 3 FileInputStream fis = new FileInputStream(file); 4 //以上的兩句代碼也可以通過以下的代碼實現: 5 //FileInputStream fis = context.openFileInput(filename); 6 byte[] data = StreamTools.getBytes(fis); 7 String result = new String(data); 8 String results[] = result.split(":"); 9 Map<String,String> map = new HashMap<String,String>(); 10 map.put("username", results[0]); 11 map.put("password", results[1]); 12 return map; 13 }
在此方法中調用了一個StreamTools.getBytes()方法,此方法是專門用來將一個InputStream流轉換為byte數組返回的,所以我們編寫此方法為:
1 package lq.wangzhen.util; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.InputStream; 5 6 public class StreamTools { 7 8 /** 9 * 把InputStream中的內容讀出來,放到一個byte[]中返回 10 * @param is 11 * @return 12 * @throws Exception 13 */ 14 public static byte[] getBytes(InputStream is) throws Exception{ 15 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 16 byte[] buffer = new byte[1024]; 17 int len = 0; 18 while((len=is.read(buffer)) != -1){ 19 baos.write(buffer, 0, len); 20 } 21 baos.flush(); 22 baos.close(); 23 return baos.toByteArray(); 24 } 25 }
最后再次修改MainActivity.java文件,調用編寫的getUserInfo方法:
1 package lq.wangzhen.file; 2 3 import java.util.Map; 4 5 import lq.wangzhen.service.FileService; 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.text.TextUtils; 9 import android.util.Log; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.widget.Button; 13 import android.widget.CheckBox; 14 import android.widget.EditText; 15 import android.widget.Toast; 16 17 public class MainActivity extends Activity implements OnClickListener { 18 19 private static final String TAG = "MainActivity"; 20 private EditText et_username; 21 private EditText et_password; 22 private Button button; 23 private CheckBox cb_remember; 24 private FileService fileService; 25 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_main); 30 31 et_username = (EditText) this.findViewById(R.id.et_username); 32 et_password = (EditText) this.findViewById(R.id.et_password); 33 button = (Button) this.findViewById(R.id.button); 34 cb_remember = (CheckBox) this.findViewById(R.id.cb_remember); 35 36 37 button.setOnClickListener(this); 38 39 //初始化文件服務 40 fileService = new FileService(this); 41 42 try { 43 Map<String,String> map = fileService.getUserInfo("private.txt"); 44 et_username.setText(map.get("username")); 45 et_password.setText(map.get("password")); 46 } catch (Exception e) { 47 // TODO Auto-generated catch block 48 e.printStackTrace(); 49 } 50 51 52 } 53 54 @Override 55 public void onClick(View v) { 56 // TODO Auto-generated method stub 57 switch (v.getId()) { 58 case R.id.button: 59 60 String username = et_username.getText().toString().trim(); 61 String password = et_password.getText().toString().trim(); 62 63 if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ 64 Toast.makeText(this, R.string.error, Toast.LENGTH_SHORT).show(); 65 return; 66 } 67 if(cb_remember.isChecked()){ 68 Log.i(TAG, "保存用戶名和密碼,"+username+":"+password); 69 try { 70 boolean result = fileService.saveToRom(password, username, "private.txt"); 71 if(result){ 72 Toast.makeText(getApplicationContext(), R.string.success, Toast.LENGTH_SHORT).show(); 73 }else{ 74 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 75 } 76 } catch (Exception e) { 77 // TODO Auto-generated catch block 78 e.printStackTrace(); 79 Toast.makeText(getApplicationContext(), R.string.failed, Toast.LENGTH_SHORT).show(); 80 } 81 } 82 break; 83 } 84 } 85 86 87 }
以上就是這次學習的全部內容,后面會繼續的對這個程序作出休整。