安卓学习第二天

本文深入探讨了软件测试的黑盒与白盒方法,包括边界用户案例、测试粒度、测试方法与功能,以及如何通过Junit框架进行方法测试。此外,详细解释了数据存储与访问技术,如文件系统、SharedPreferences、SQLite数据库、内容提供者和网络存储,并提供了Android应用中文件权限的管理策略。最后,介绍了XML文件的Pull解析原理及在Android应用中的应用,以及如何使用SQLite数据库存储数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何对软件进行测试:

1.黑盒测试
	不知道软件的源代码,从软件的界面和功能上测试软件工作是否正常.
        边界用户案例.
	
2.白盒测试
         知道软件的源代码, 对软件的某个方法,某个功能,某个模块,进行测试.
        测试粒度:
        测试方法: junit的框架进行方法测试.
        测试功能:  function test.  一般会有测试用例(user story)
        测试模块:  集成测试,与服务器联调.

好的软件不写出来,是测出来的.




计算机 给数据打交道.
其实计算机就是把某些数据给处理一下然后再返回。

数字电路 : 与门 或门 与非门 
汇编代码 : 把某个寄存器里面的值  放到另外一个寄存器里面
c 语言   : int add(int x,int y) 
java     : 

---数据在程序都是在内存.

---持久化数据的设备:  硬盘 u盘 rom 




通过context的openfileoutput() 
创建的文件:
data/data/<包名>/files/config.txt 

存放手机rom内存里面的.


03-10 10:22:33.432: WARN/System.err(5421): java.io.FileNotFoundException: /data/data/cn.itcast.datasave/files/config.txt (Permission denied)
03-10 10:22:33.464: WARN/System.err(5421):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-10 10:22:33.464: WARN/System.err(5421):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-10 10:22:33.464: WARN/System.err(5421):     at java.io.FileInputStream.<init>(FileInputStream.java:82)
03-10 10:22:33.482: WARN/System.err(5421):     at cn.itcast.dataread.MainActivity.onCreate(MainActivity.java:33)
03-10 10:22:33.482: WARN/System.err(5421):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-10 10:22:33.482: WARN/System.err(5421):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-10 10:22:33.482: WARN/System.err(5421):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-10 10:22:33.482: WARN/System.err(5421):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-10 10:22:33.482: WARN/System.err(5421):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-10 10:22:33.482: WARN/System.err(5421):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-10 10:22:33.508: WARN/System.err(5421):     at android.os.Looper.loop(Looper.java:123)
03-10 10:22:33.508: WARN/System.err(5421):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-10 10:22:33.508: WARN/System.err(5421):     at java.lang.reflect.Method.invokeNative(Native Method)
03-10 10:22:33.508: WARN/System.err(5421):     at java.lang.reflect.Method.invoke(Method.java:521)
03-10 10:22:33.508: WARN/System.err(5421):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-10 10:22:33.512: WARN/System.err(5421):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-10 10:22:33.512: WARN/System.err(5421):     at dalvik.system.NativeStart.main(Native Method)




如果我们应用在当前包下创建了一个文件,并且我们希望别的应用程序 可以访问我们的文件 
一定要指定文件的权限  Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE

如果我们不希望别人修改,访问你的数据
Context.MODE_PRIVATE


如果我们希望每次存取数据 都是以追加方式 
Context.MODE_APPEND 默认文件的访问修饰权限 是私有 

以私有方式创建的文件  permissions -rw-rw----
全局可读           		  -rw-rw-r--
全局可写		          -rw-rw--w-
全局可读写                        -rw-rw-rw-


linux 系统的文件的访问权限 
第一个 - 代表文件
       d  代表目录
- | rw- |  rw-   | ---
当前用户   用户组  其他人 

android下面每一个应用程序 操作系统都会给他分配一个用户名 

File cacheDir =  this.getCacheDir();
程序的临时数据可以存放到这个目录
用户可以手工清除掉这个目录里面的内容 











开发android下的天气预报 
1. 连接服务器. 

<xml >
<info>
	<city>北京</city>
	<temp>10°</temp>
	<wind>东风</wind>
	<type>晴天</type>
</info>


textview 
imageview




手机有短信 联系人 
<xml 头>
<smss>
	<sms id = "1">
		<sender>15555215556</sender>
		<body>haha</body>
		<time>3月9日</time>
	</sms>


</smss>

StringBuilder sb = new StringBudiler();
sb.append();

土办法. 




sqlite数据库 是一个开源项目.
c/c++ 
轻量级的关系型数据库
iphone 
android 



java web 操作数据库 

jdbc 操作数据库

1. 加载数据库驱动.
2. 获取到连接对象.
3. exec(sql);

=========================================================================
1、单元测试
在实际开发中,开发android软件的过程需要不断地进行测试。而使用Junit测试框架,侧是正规Android开发的必用技术,
在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性。
第一步:首先在AndroidManifest.xml中加入下面红色代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="cn.itcast.action“ android:versionCode="1“  android:versionName="1.0">
 <application android:icon="@drawable/icon" android:label="@string/app_name">
        <uses-library android:name="android.test.runner" />
        ....
 </application>
 <uses-sdk android:minSdkVersion="6" />
 <instrumentation android:name="android.test.InstrumentationTestRunner"
  android:targetPackage="cn.itcast.action" android:label="Tests for My App" />
</manifest>
上面targetPackage指定的包要和应用的package相同。
第二步:编写单元测试代码(选择要测试的方法,右键点击“Run As”--“Android Junit Test” ):
import android.test.AndroidTestCase;
import android.util.Log;
public class XMLTest extends AndroidTestCase {
	 public void testSomething() throws Throwable {
		Assert.assertTrue(1 + 1 == 3);
	 }

2、数据存储与访问
很多时候我们的软件需要对处理后的数据进行存储或再次访问。Android为数据存储提供了如下几种方式:
1)文件(ROM,SD卡)
2)SharedPreferences(参数)
3)SQLite数据库
4)内容提供者(Content provider)
5)网络
我们所说的手机内存是RAM,而手机自带内存是ROM,手机可以插的内存卡叫外存。
/**
	上下文,其实是执行时它的这个全局环境变量,Context本身是一个抽象类,里面有
	大量的包含的此时执行的一些信息,只要你获得正在执行的Activity的上下文
	就可以大胆去获取很多东西,其实Activity也继承了Context这个类,不同的执行环境
	当然它的上下文也是不一样的,所以在不同的环境下要动态获取不同的。
*/
	//定义一个未初始化的上下文,在哪个activity里面用,肯定就传入谁的上下文,所有
	//写这样一个构造 方法,让它直接把当时环境 下的上下文章传进去 。
	//然后这里面的所有方法就适用于所有activiy中的上下文了。
	private Context context;	
	public SavePwdService(Context context){
		this.context = context;
	}
//这是一种非常好的写法。
//还有一种对静态常量的写法,十分好。
private static SmsManager sInstance;
public static SmsManager getDefault() {
        if (sInstance == null) {
            sInstance = new SmsManager();
        }
        return sInstance;
    }
/**
通过context的openfileoutput() 
创建的文件:
data/data/<包名>/files/config.txt 
存放手机rom内存里面的.
**/
/**权限问题**/
//三种权限一种追加。
Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE:表示其它人可以读和写我们的文件。
Context.MODE_PRIVATE  如果我们不希望别人修改和访问你的数据
如果我们希望每次存取数据 都是以追加方式 Context.MODE_APPEND 默认文件的访问修饰权限 是私有
也就是别人不能读也不能写,只有自己的程序能够操作。
自己:创建该文件的程序  其它:其它程序

权限原理(其实就是Linux管理下的文件系统,太他妈简单了):
以私有方式创建的文件  permissions -rw-rw----
全局可读           		          -rw-rw-r--
全局可写		                  -rw-rw--w-
全局可读写                        -rw-rw-rw-

linux 系统的文件的访问权限 
第一个 - 代表文件
       d  代表目录
- | rw- |  rw-   | ---
当前用户   用户组  其他人 
/**
android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,
当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,
任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),
其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,
只有这样其他程序才能正确访问。
所以安卓的每一个应用程序,安卓都会给它分配一个用户名,这样才能利用linux的这种
用户的管理权限来实现安卓的管理权限。
*/
/**
	 * @param name
	 * @param pwd
	 * @throws IOException 
	 * 把数据存储到ROM上
	 */
	public void saveToRomFile(String name,String pwd) throws IOException{
		FileOutputStream fos = context.openFileOutput("config.txt", Context.MODE_PRIVATE);
		String content = name +":"+pwd;
		fos.write(content.getBytes());
		fos.flush();
		fos.close();;
	}
	/**
	 * @param name
	 * @param pwd
	 * @throws IOException
	 * 数据存储到SD卡上
	 */
	public void saveToSdCard(String name,String pwd) throws IOException{
		//判断当前 SD卡的状态是处于可以访问的状的时间
		if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
			//得到一个文件对象 
			File file = new File(Environment.getExternalStorageDirectory(),"newfile.txt");
			FileOutputStream fos = new FileOutputStream(file);
			String content = name + ":" + pwd;
			fos.write(content.getBytes());
			fos.flush();
			fos.close();
		}
	}
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//获取内存卡的大小 。
public void testSDsize() throws Exception{
	    File path = Environment.getExternalStorageDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = stat.getBlockSize();
        long totalBlocks = stat.getBlockCount();
        long totalbytes =  blockSize*totalBlocks;
        System.out.println(totalbytes);
}	
2)SharedPreferences(参数)--用于保存软件的一些参数。

//补充知识
File cacheDir =  this.getCacheDir();
程序的临时数据可以存放到这个目录
用户可以手工清除掉这个目录里面的内容 

//Pull解析的原理 
一行解析完以后才解析下一行。
在循环里面parse.Next()之上的语句全部都是在解析同一行。且记。
解析XMl文件有三种方式。
1)、sax解析,
SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。
 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,
 在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,
 如果符合就会触发事件
2)、 DOM解析XML文件时,会将XML文件的所有内容以文档树方式存放在内存中,
然后允许您使用DOM API遍历XML树、检索所需的数据。使用DOM操作XML的代码看起来是比较直观的,
并且在编码方面比基于SAX的实现更加简单。但是,因为DOM需要将XML文件的所有内容以文档树方式存放在内存中,
所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,
所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM也是可行的。
3)、pull解析。与SAX解析比较像,因为它也是基于事件解析,是从上而下的,而且是无法回头的。
是一行一行的,这点要深刻理解。循环之内都是解析的一行,只有调用 next()之后才到下一行。

	private Context context;

	public PersonService(Context context) {
		this.context = context;
	}
	//我现在感觉它是一种设计模式,这样可以让其它程序调用的时间,传入自己的上下文,正好可以用。
	//太奇妙了。

3、关于测试一些知识。
第一、导入包
第二、继承AndroidTestCase 
第三、方法要抛出异常,否则测试框架得不到。
第四、它提供了一个模拟的下下文可以供我们来测试。
4、使用Pull解析器生成XML文件(不用以前的土办法,因为它太容易出错了。)
	1)XML的标准格式是没有换行和空格的。
	2)/sdcard/person.xml 写成这种形式只要加一个写的SD卡权限即可
		如果getExternalStorageDirectory()要加unmount权限。
	3)这个东西非常简单,比传统拼字符的方式要好很多。
public boolean ListToXml(List<Person> persons){
		try {
			XmlSerializer serializer = Xml.newSerializer();
			// /sdcard/person.xml 
			// mount unmount 文件系统的权限 
			File file = null;
			if (Environment.MEDIA_MOUNTED.equals(Environment
					.getExternalStorageState())) {
				file = new File(Environment.getExternalStorageDirectory(),
						"persons.xml");
			}
			FileOutputStream fos = new FileOutputStream(file);
			//Set to use binary output stream with given encoding.
			serializer.setOutput(fos, "utf-8");
			//This method can only be called just after setOutput.
			serializer.startDocument("utf-8", true);
			
			serializer.startTag(null, "persons");
			for(Person person : persons){
				serializer.startTag(null, "person");
				
				serializer.attribute(null, "id", person.getId()+"");
				
				serializer.startTag(null, "name");
				serializer.text(person.getName());
				serializer.endTag(null, "name");
				
				serializer.startTag(null, "age");
				serializer.text(person.getAge()+"");
				serializer.endTag(null, "age");
				
				serializer.endTag(null, "person");
			}
			serializer.endTag(null, "persons");
			
			serializer.endDocument();//Finish writing.
			fos.flush();
			fos.close();
			return true;
		} catch (Exception e) {
			
		}
		return false;
	}

5)数据库(使用嵌入式关系型SQLite数据库存储数据)
sqlite数据库 是一个开源项目.
底层:c/c++ 
轻量级的关系型数据库
iphone  android  HTML5均是用这个开源的数据库。
它不会去检查你的数据类型,也就是说,它不会,
就检查你存入的数据类型,这也是他高效的原因。
 回忆一下:
 

java web 操作数据库 

jdbc 操作数据库

1. 加载数据库驱动.
2. 获取到连接对象.
3. exec(sql);

但是由于安卓自身就一个数据库,所以不用去加载驱动,自己有连接对象,
直接去执行SQL语句就行了。

getReadableDatabase()并不是以只读方式打开数据库,而是先执行getWritableDatabase(),失败的情况下才调用。
 getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。
 但getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,
 getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,
 倘若使用如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。 
 
 也就是说,在往数据库里面写东西的时间,一次只能由一个线程往里面写,因为它加了锁,但是在读的时间
 可以多个同时读取。
 
 












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值