创建一个apk:按钮-click-文字display,测试apk;安装在真机进行调试的方法

问题引入:

怎么样在一个app做event事件?例如touch操作,滑动操作,和按键事件(back,home等)

回答1:device.touch(x,y) ---获取device对象,然后touch操作,这是monkeyrunner选手,用了monkeyrunner类,基于坐标

回答2:solo.clickOnView(string)---Robtium选手,使用solo类,里面很多方法查找控件,点击这样一个视图,把ID传进去,点击即可。基于控件的自动化框架

回答3:driver.findElement(By.name("Add contact".click())) ---selenium选手,定义浏览器driver,只要拿到核心driver,就能实现

回答4:不允许用任何开源的和不开源的自动化框架,howto?---Instrumentation选手,使用google基类完成

20140424

思路:

新建apk项目 - > 新增Button 、TextView ->在按钮点击事件里里添加获取TextView的内容

1. 使用Eclipse新建项目。 

2. 根据Google release文档,图形化界面使用view实现,Android对于ViewViewGroup的子类提供一系列基于XML的命名和定义,因此,可以用XML来定义用户界面。sdk 4.4使用fragment代替了原来写死的布局。一方面更能体现出模块化设计,另一方面对于不同屏幕尺寸的适配也更为容易。好吧,在fragment_main.xml中捣鼓:顺序是linearlayout布局设定,添加需要的组件,组件里用到资源的,到values文件夹下添加。

Tips:遇到的标签:

RelativeLayout--- 相对布局可以控制组件摆放的位置(放在任一组件的上下左右等位置) 参考http://blog.csdn.net/kaypro/article/details/10156773

LinearLayout --水平布局 http://www.cnblogs.com/songtzu/archive/2012/07/11/2586462.html

二者对比:http://blog.csdn.net/renzhe333/article/details/12970565

基于此,我们使用LinerLayout,然后里面放个button和Textview

到这里,此布局将被用于在创建项目时SDK工具生成的缺省Activity类,现在可以通过运行一下,已经看到界面出来啦。

3. 添加按钮响应事件,同时需要将默认textview值隐藏,待点击后方可出现。

Tips:

所有“Activity”的子类必须实现“onCreate()”方法。当系统创建一个此activity的新实例的时候,将调用此方法。这个方法就是你使用“setContentView()”方法定义activity布局和为activity的各个构件(components)初始化设置(initial setup)的地方。

要在屏幕上显示这则消息,需要创建一个“TextView”部件(widget)然后通过“setText()”方法设置它的显示文字。因此,通过“setContentView()”方法,将“TextView”添加到布局中作为activity的根视图元素。

不过此处不用更改onCreate(),因为并没有新建一个Activity,只是把OnClick方法中实现TexView

 20140425
写完了被测试apk,发现无法监控到测试apk,给按钮加了监听,然后杯具地出现nullpionterexception,出现的位置就是this.findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener);问题解决:setContentView(R.layout.fragment_apk4_main)这句需要放在整个onCreate的最上面(出了super.onCreate)外!!!否则程序无法找到注册的控件信息,我是在fragment中添加了button和textview,因此这里改掉了。
public class APK4MainActivity extends ActionBarActivity {
    
    private TextView tv = null;
    //View.OnClickListener mOnClickListener = null;
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.fragment_apk4_main); // this code always should be put forward.
            
        tv = (TextView) this.findViewById(R.id.textview1);
        Button button=(Button)this.findViewById(R.id.btn1);
        button.setOnClickListener(mOnClickListener);

        
        }
        
     View.OnClickListener mOnClickListener = new View.OnClickListener() {
    // mOnClickListener = new View.OnClickListener() {
                
        public void onClick(View v) {
            //send_msg(v);

            if(v.getId()== R.id.btn1) //由于有很多中view的onCLick事件,系统需要知道是不是buttonID的事件,因此获取view的ID
            tv.setText("OKKK");

        }
        
         
    };
    

 

测试apk编写要点:
1. 基于Junit4创建,默认类的内容和Junit很像:
Instrumentation在android.test pkg中,写测试用例肯定要用到InstrumentationTestCase类:setup()\run()\teardown()分别实现,这和Junit是一样的。大概内容如下:(使用Runnable接口而不是InstrumentationTestRunner)
public class testapk4ianthe extends InstrumentationTestCase{
   //明确一个Activity,让Instrumentation找到目标apk的主Activity入口类  
    APK4MainActivity mActivity = null;
  //声明button变量,用来存放下面用findViewByID得到的button控件
private Button btn1 = null;
//声明textview变量,用来存放findVIewByID得到的TextView控件
private TextView tv1 = null;   //为ddms行方便,查看log private static final String tag="ianthe"; /** * @测试setUP初始化 */ @Before public void setUp() throws Exception { //这是程序初始化过程,第一步是调用父类方法 super.setUp(); // 初始化意图请求 Intent intent = new Intent(); //通过找到包 - 类名,让intent知道程序源的信息 intent.setClassName("com.example.apk4ianthe", APK4MainActivity.class.getName());
     //设置intent标志位,这个参数常用在setup中。Activity的intent跳转到另外Activity有四种模式,这是标准模式 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //重要函数getInstrumentation()登场!!!它用来得到Instrumentation实例,相当于new Instrumentation,之后可以使用Instrumentation中的方法了。得到目标Activity的主入口(其实哪个Activity启是在menifest.xml中指定好的) mActivity
= (APK4MainActivity) getInstrumentation().startActivitySync(intent);
     //找到被测试apk的主要控件 tv1
=(TextView)mActivity.findViewById(R.id.textview1); btn1=(Button)mActivity.findViewById(R.id.btn1); } @Test public void test() throws Exception{ //健壮性测试 for (int i = 0;i <5;i++){
        //阻塞性方法,比如如果主线程timeout了,则整个没有响应;如果是网络下载按钮,则timeout后出现ANR. runOnMainSync()需要一个线程类对象,提出来单独写比较好。 getInstrumentation().runOnMainSync(
new PerformClick(btn1)); SystemClock.sleep(500); Log.i(tag, "-----点击!!"); } assertEquals("OKKK",tv1.getText().toString()); } private class PerformClick implements Runnable{ Button btn; public PerformClick(Button button){ btn = button; } @Override public void run(){ btn.performClick(); } }

 经常遇到的问题是,缓存问题。解决方法是重启Eclipse。写java文件之前,要记得在AndroidMenifest.xml中添加:

<instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="被测包名" />

以防万一,在<application>里面加入<uses-library android:name="android.test.runner" />

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);这里涉及到Activity启动模式(需要在menifest.xml中设置),查了资料大概这样子的:
术语:任务栈 : 内部实现是链表,后进先出
standard ---标准默认启动模式,menifest里不加说明时,就是用的这种。activity按照先后顺序依次压入任务栈,再依次销毁。
singleTop---如果人物栈的栈顶元素,是要被激活的组件,不会创建新的Activity放在任务栈,而会复用栈顶的Activity。如果发现栈顶不是要激活的Activity,就会创建信的Activity放置到任务栈里面。使用场景:打开书签页,一口气添加N个书签,然后返回,用户体验好的情况是,按一次返回键就回到主标签Activity页,即此种模式,而不是一次一次回退到头。。。
singleTask---一般情况下,跟singletop类似:如果发现任务栈里已经有了要启动的Activity,它会去清空这个Activity上面的所有Activity,然后直接复用已经存在的Activity。场景:浏览器应用:BrowserActibity -> 开销很大,原理在于初始化webkit/c++嵌入式浏览器内核。为了节省开销,把broweractivity配置成singleTask,则可以复用 -- 以空间换时间
singleInstance--会开启一个新的任务栈,把要激活的actibity放置到新的任务栈里面。这个任务栈里面只有一个实例。不想被放到默认的任务栈里面,新开辟一个任务栈。场景:有道词典,在notification里点击直接进入查询界面,这个界面和有道主程序无关。
 
那么怎么知道用的哪种启动模式呢?可以在Activity程序的onResume里面加入system.out.println("task id="+getTaskId());不同任务栈的task id不同滴。onresume是界面获取到焦点时使用的方法,只要我们开启新的Activity,就会获取到新的焦点
 
==========
安装在真机上进行调试:
1. 在apk的menifest文件中,把debuggable设置为true;也就是说<application
android:debuggable = "true" /> 如果发布到市场上,一定去掉这句话
posted on 2014-04-25 01:56  麦兜布熊  阅读(942)  评论(0编辑  收藏  举报