android开发菜鸟遇到的炕

        最近公司组织进行无线开发大赛,旨在提升团队的无线开发能力,还有大奖呵呵,抱着学习的态度,也没想拿奖,就一个人报名了,服务端和客户端自己搞定,作为服务端开发经验丰富,一天多的时间就搞定了,但是android的开发花了很多时间,中间有很多坑,最后也算能够交差了。

        开发环境搭建就不写了,网上资料很多,大致就是下载android 的SDK,添加android开发的eclipse插件,然后eclipse中关联SDK,就OK了。

(1)请求http接口,网络权限问题

         这是遇到的第一个问题,之前纳闷android是如何发起网络请求的,搜了些文章发现原来是通过httpclient,然后写好httpclient代码,但是请求不到服务端,找了半天,原始是android的这个文件AndroidManifest.xml,需要开通权限。

        在android中通过Httpclient请求外部的服务是,会报这个错误java.net.UnknownHostException,原因是代码中没有设置访问网络的权限,在AndroidManifest.xml中添加这个配置即可  <uses-permission android:name="android.permission.INTERNET"/>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
List<BasicNameValuePair> params =  new  LinkedList<BasicNameValuePair>();
params.add( new  BasicNameValuePair( "userId" , String.valueOf(userId)));
params.add( new  BasicNameValuePair( "dateId" , String.valueOf(dateId)));
String param = URLEncodedUtils.format(params,  "UTF-8" );
  //这个大家都懂,添加参数
HttpClient client = HttpClientUtil.getHttpClient();
HttpGet get =  new  HttpGet(AppConstant.DOMAIN+param);
HttpResponse response = client.execute(get);
BufferedReader reader =  null ;
HttpEntity entity = response.getEntity();
reader =  new  BufferedReader( new  InputStreamReader(entity.getContent(),  "gbk" ));
//获取Content,然后创建stream
StringBuilder sb =  new  StringBuilder();
for  (String s = reader.readLine(); s !=  null ; s = reader.readLine()) {
       sb.append(s);
}

(2)activity没有熟悉例子,只是想到啥就做啥

        在做产品规划的时候,没有设计,自己想到啥就去做啥了,页面也是这样,基本上想到啥样就去调整了, 现在想来,这是一个失误,应该把之前android支持的组件先熟悉一遍,能够做到灵活运用,这样就好了。。。

(3)依赖外部的jar包,如何打入到apk中

        android中如果要添加外部的jar包,需要把jar包拷到libs目录下面,否则如果仅仅关联了classpath,那样运行在模拟机上的话会报错,java.lang.NoClassDefFoundError这个异常。当时怀疑,android项目是这样来添加jar包的?岂不是很低级?升级一次jar包会是一件头疼的事情,然后网上找了一下,maven官方没有提供工具,android也没有,但是开源有个插件 maven-android-plugin,能够把android构建成maven项目,这样添加jar包,导入apk文件,是一件很容易的事情。

(4)MTOP怎么使用(MTOP 一淘无线团队的开放平台,提供了复用的组件)

        app中有个淘宝账号登陆的功能,当时觉得麻烦,打算复用一淘无线团队中的组件,了解了半天,发现接入起来太费劲,要申请一些列东西,就放弃了。但是了解的这个过程还是有收获,后续开发,尽量把公共功能组件化,减少开发成本,然后api接口的话设计灵活巧妙。

(5)关于退出app

        关于应用退出这个功能,自己在使用app的时候,比较喜欢按两次back键来完成退出,然后打算自己在功能中实现这个。在晚上找了一下,基本上是这种代码,说的比较简单,“监听back事件,然后把activity状态变为finish”,

但是在写完代码后遇到一个问题,就是只能退出当前的activity,连续双击后,展示出了这个activity的上一个activity,这个有点体验不好,然后继续找资料,最后的解决方案。

A、搞了一个父类,继承Activity,然后其他自定义的Activity实现这个基类,基类中重写onCreate这个方法;

B、在onCreate方法中,构造单例,把当前的Activity对象添加到列表中;

1
2
3
4
public  void  onCreate(Bundle savedInstanceState) {
             super .onCreate(savedInstanceState);
             ActivityList.getInstance().addActivity( this );
      }

C、然后在父类中监听onBackPressed这个事件,就是点击“back”的操作;

D、符合退出条件的情况下,在单例中,把存储在列表中的activity对象依次finish,这样就实现退出了;

1
2
3
4
5
6
7
8
9
10
11
12
13
     long  waitTime =  2000 ;
     long  touchTime =  0 ;
     //监听后退按键
     @Override
     public  void  onBackPressed() {
            long  currentTime = System.currentTimeMillis();
            if ((currentTime-touchTime)>=waitTime) {
                Toast.makeText( this "哈哈,再按一次,就退出瞄过往了" , Toast.LENGTH_SHORT).show();
                touchTime = currentTime;
            } else  {
               ActivityList.getInstance().exit();
            }
     }

(6)handle机制

        在App中有种情况,就是请求网络中的数据,这一步是很耗时的,所以就想异步来做,自己就new Thread来请求数据,把数据放到缓存中,但是有个问题,就是需要搞一个“加载中”的提示,当时以为很简单,在new出来的线程中调用了一下ProgressBar的消失方法,但是运行的时候抛出异常,说是不能new线程,但是反复试了很多办法,但是没有解决。

        此时,就想把加载数据改成同步,这样就不会有问题了,但是试了一下,在等待网络请求的时候,超过5秒的时间,android就会弹出层,说是系统没响应,是否要强制关闭。

        于是有开始想办法,此时找到了这篇文章:http://www.pin5i.com/showtopic-android-handler.html​

        原来关于Activity的相关UI操作,只能由主线程来进行(因为是非线程安全的)。Handler就出现了,来解决这个复杂的问题 ,    由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

        继承Handle类:   

1
2
3
4
5
6
7
8
9
10
11
12
13
class  MyHandler  extends  Handler {
       public  MyHandler() {
       }
       public  MyHandler(Looper L) {
           super (L);
       }
       // 子类必须重写此方法,接受数据
       @Override
       public  void  handleMessage(Message msg) {
           super .handleMessage(msg);
           MainActivity. this .dialog.dismiss();
       }
   }

        然后在异步线程中调用Handle来传递数据,完成UI的变化:MainActivity.this.handle.handleMessage(null);

(7)android中的异步

        在这次APP中,异步的任务是通过new Thread的方式来进行的,虽然问题解决了,但是觉得有点山寨,搜了一下,发现android中提供了方案AsyncTask来满足这个需求。

        ​​

        子类必须实现AsyncTask中的doInBackground(Params...)这个方法。

        AsynTask类在继承时要传入3个泛型。第一个泛型对应execute()向doInBackground()的传递类型。第二个泛型对应doInBackground()的返回类型和传递给onPostExecute()的类型。第三个泛型对应publishProgress()向progressUpdate()传递的类型,这个是用来通知主线程,例如数据加载进度等。

(8)数据的埋点

        这次app中,为了了解用户的使用情况,在友盟哪里找了个工具,把系统的埋点做了下,在Activity中,有各个状态,resume和pause,然后在父类中添加埋点,剩下的事情交给友盟去做了,然后既可以在友盟提供的页面上看到数据了。友盟获取机器的UMID信息后,然后结合配置文件中的appkey,既可以定位唯一的一台机器,然后结合埋点数据,分析出结果,个人觉得很好用,接入一个小时就够了。

1
2
3
4
5
6
7
8
public  void  onResume() {
           super .onResume();
           MobclickAgent.onResume( this );
     }
     public  void  onPause() {
           super .onPause();
           MobclickAgent.onPause( this );
     }

    ​​​

 

 

你可能感兴趣的:(Android开发)