Android

来自tomtalk
跳转至: 导航搜索

笔记

http://code.metager.de/source/xref/android/ android源码

Android应用开发视频教程-第1季

Android应用开发视频教程-第2季

https://code.google.com/p/android-json-rpc/

https://code.google.com/p/android-shuffle/

https://github.com/stephanenicolas/robospice

https://github.com/47deg/android-swipelistview

http://techmeme.com/

Android的知识结构(源代码方面):

  1. Linux操作系统知识
  2. Linux内核知识(C语言)
  3. Linux驱动程序知识(C语言)
  4. Android底层库(C语言、C++)
  5. Dalvik虚拟机(C++、JAVA)
  6. Android GUI系统(C++、JAVA)
  7. 音频、视频和多媒体(C语言、C++、JAVA)
  8. 电话部分的(C语言、C++、JAVA)
  9. 连接部分(C语言、C++、JAVA)
  10. 传感器部分(C语言、C++、JAVA)

Android的知识结构(SDK方面):

  1. JAVA语言知识
  2. 应用程序架构
  3. GUI设计基础知识
  4. 各种视图的使用
  5. 2D/3D图形API
  6. 应用程序的设计思想

Android的开发分成三种类型: 1. 移植开发手机系统 2. 应用程序开发 3. Android系统开发

Android是包括一个操作系统、中间件和关键应用的移动设备的一个软件堆。

Android开发环境搭建

http://hi.baidu.com/wlj1013/item/3e6080351168b9302f0f815c

Eclipse快捷键

http://www.jb51.net/article/32603.htm

Ctrl + 1 快速修复错误 Ctrl + Shift + O 自动补全引用类

精通android

PA01 Android计算机平台简介
PA02 设置开发环境
PA03 使用Android资源
PA04 ContentProvider
PA05 Intent
PA06 建构用户界面和使用控件
PA07 使用菜单
PA08 使用对话框
PA09 管理和组织首选项
PA10 探索安全性和权限
PA11 构建和使用服务
PA12
PA13 处理程序
PA14 广播接收程序和长期运行的服务
PA15 闹钟管理器
PA16 2D动画揭秘

PA17 地图和基于位置的服务
PA18 电话API
PA19 媒体框架
PA20 使用OpenGL进行3D图形编程
PA21 活动文件夹
PA22 主屏幕部件
PA23 Android搜索
PA24 文本到语音转换
PA25 触摸屏幕
PA26 传感器
PA27 联系人API
PA28 使用Android Market
PA29 多用途的碎片
PA30 ActionBar
PA31 3.0版本中的更多主题
EOF

bookmarks

Android概念题

1. int 和 Integer 有什么区别

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。

原始类型封装类

boolean-Boolean、char-Character、byte-Byte、short-Short、int-Integer、long-Long、float-Float、double-Double

引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。

2. final, finally, finalize的区别。

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

finally是异常处理语句结构的一部分,表示总是执行。

finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

3. Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

4. 运行时异常与一般异常有何异同?

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。

5. 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?

对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。

6. 多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

多线程有两种实现方法,分别是继承Thread类与实现Runnable接口

同步的实现方面有两种,分别是synchronized,wait与notify

7. abstract class和interface有什么区别?

声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口

8. Activity和Task的启动模式有哪些?

standard: 标准模式 ,一调用 startActivity() 方法就会产生一个新的实例。 singleTop : 如果已经有一个实例位于 Activity 栈的顶部时,就不产生新的实例,而只是调用 Activity中的 newInstance() 方法。如果不位于栈顶,会产生一个新的实例。 singleTask : 会在一个新的 task 中产生这个实例,以后每次调用都会使用这个,不会去产生新的实例了。 singleInstance : 这个跟 singleTask 基本上是一样,只有一个区别:在这个模式下的 Activity 实例所处的 task 中,只能有这个 activity 实例,不能有其他的实例。

9. 通过Intent传递一些二进制数据的方法有哪些?

a. 使用Serializable接口实现序列化。 b. 实现Parcelable接口。

10. handler机制的原理

andriod 提供了 Handler 和 Looper 来满足线程间的通信。 Handler 先进先出原则。 Looper 类用来管理特定线程内对象之间的消息交换 (Message Exchange) 。

1)Looper: 一个线程可以产生一个 Looper 对象,由它来管理此线程里的 Message Queue( 消息队列 ) 。 2)Handler: 你可以构造 Handler 对象来与 Looper 沟通,以便 push 新消息到 Message Queue 里; 或者接收 Looper 从 Message Queue 取出 ) 所送来的消息。 3)Message Queue( 消息队列 ): 用来存放线程放入的消息。 4)线程: UI thread 通常就是 main thread ,而 Android 启动程序时会替它建立一个 Message Queue 。

11. android中线程与线程,进程与进程之间如何通信

a 、一个 Android 程序开始运行时,会单独启动一个 Process 。

默认情况下,所有这个程序中的 Activity 或者 Service 都会跑在这个 Process 。

默认情况下,一个 Android 程序也只有一个 Process ,但一个 Process 下却可以有许多个 Thread。

b 、一个 Android 程序开始运行时,就有一个主线程 Main Thread 被创建。该线程主要负责 UI 界面的显示、更新和控件交互,所以又叫 UI Thread 。

一个 Android 程序创建之初,一个 Process 呈现的是单线程模型 — 即 Main Thread ,所有的任务都在一个线程中运行。所以, Main Thread 所调用的每一个函数,其耗时应该越短越好。而对于比较费时的工作,应该设法交给子线程去做,以避免阻塞主线程(主线程被阻塞,会导致程序假死 现象)。

c 、 Android 单线程模型: Android UI 操作并不是线程安全的并且这些操作必须在 UI 线程中执行。如果在子线程中直接修改 UI ,会导致异常。

12. 请介绍下 Android 中常用的五种布局

FrameLayout (框架布局), LinearLayout (线性布局), AbsoluteLayout (绝对布局), RelativeLayout (相对布局), TableLayout (表格布局)。

12. 什么是ANR? 如何避免它 ?

ANR : Application Not Responding ,五秒 在 Android 中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时, Android 就会显示 ANR 对话框了: 对输入事件 ( 如按键、触摸屏事件 ) 的响应超过 5 秒 意向接受器 (intentReceiver) 超过 10 秒钟仍未执行完毕 Android 应用程序完全运行在一个独立的线程中 ( 例如 main) 。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发 ANR 。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播 (Intent broadcast) 。

因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如 onCreate() 和 onResume() 等更应如此。潜在的比较耗时的操作,如访问网络和数据库; 或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成 ( 或者是使用异步请求,如数据库操作 ) 。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束 — 也不需要调用 Therad.wait() 或者 Thread.sleep() 方法。取而代之的是,主线程为子线程提供一个句柄(Handler) ,让子线程在即将结束的时候调用它 。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过 5 秒钟不被处理而产生的 ANR 。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

android 算法题

1. 有1000盏灯泡,第一轮点亮所有电灯,第二轮每两盏灯熄灭一盏,即熄灭第2盏,第4盏,以此类推,第三轮改变编号为3的倍数的电灯,第3盏,第6盏,如果原来那盏灯是亮的,就熄灭它,如果原来是灭的,就点亮它,以此类推,直到第1000轮。问第1000轮结束后,还有多少盏灯泡是亮的?

答案:31盏

2. 用伪代码编写一个函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的。

char * search(char *cpSource, char ch) {

        char *cpTemp=NULL, *cpDest=NULL;
        int iTemp, iCount=0;
        while(*cpSource)
        {
                if(*cpSource == ch)
                {
                         iTemp = 0;
                         cpTemp = cpSource;
                         while(*cpSource == ch)
                              ++iTemp, ++cpSource;
                         if(iTemp > iCount)
                             iCount = iTemp, cpDest = cpTemp;
                        if(!*cpSource)
                             break;
                }
                ++cpSource;
      }
       return cpDest;

}

3. 请用伪代码实现在小于99999的正整数中找符合下列条件的数,它既是完全平方数,又有两位数字相同,如:144,676。(不能用数字转换成字符串)

int havesamenum(int num) {

   int i=0,j;
   char a[10] = {0};
   while(num>0)
   {
       j=num%10;
       a[j]+=1;
       num=num/10;
   }
   while(a[i]<=1&&i<10)
       i++;
   if (i<10)
       return 1;
   else
       return 0;

}

void main(void) {

   int i,j,m;
   m=(int)sqrt(99999);
   for(i=1;i<m;i++)
   {
       j=i*i;
       if (1==havesamenum(j))
           printf("%6d\t",j);
   }

}

4、用伪代码实现: 求n个数(1....n)中k个数的组合.... ? 如:n=5,k=3 输出:543,542,541,532,531,521,432,431,421,321

int pop(int *); int push(int ); void combination(int ,int);

int stack[3]={0}; int top = -1;

void combination(int m,int n) {

   int temp = m;
   push(temp);
   while(1)
   {
       if(1==temp)
       {
           if(pop(&temp) && stack[0]==n)
               break;
       }
       else if(push(--temp))
       {
           printf("%d%d%d\n",stack[0],stack[1],stack[2]);
           pop(&temp);
       }
   }

}

int push(int i) {

   stack[++top]=i;
   if(top<2)
       return 0;
   else
       return 1;

}

int pop(int *i) {

   *i = stack[top--];
   if(top>=0)
       return 0;
   else
       return 1;

}

5、有两个数组a,b,大小都为n, 数组元素的值任意整数,无序;?要求:通过交换a,b中的元素,使[数组a元素的和]与[数组b元素的和]之间的差最小。?(用伪代码实现) 例如: var a=[100,99,98,1,2, 3];

    var b=[1, 2, 3, 4,5,40];

bool Swap2Balance(int *pa, int *pb, int n) {

   int suma=0,sumb=0;
   for (int i=0;i<n;i++)
   {
       suma+=pa[i];
       sumb+=pb[i];
   }
   int diff=suma-sumb;
   while (diff!=0)
   {
       int besti=0,bestj=0;
       int bestchange=0;
       for(int i=0;i<n;i++)
           for (int j=0;j<n;j++)
           {
               int change=(pa[i]-pb[j]);
               //交换后差为(suma-pa[i]+pb[j])-(sumb+pa[i]-pb[j])=diff-2*change
               if (abs(diff-2*change)<abs(diff-2*bestchange))
               {
                   bestchange=change;
                   besti=i;
                   bestj=j;
               }
           }
       if (bestchange==0)    //差不能再缩小
           return false;
       int temp=pa[besti];
       pa[besti]=pb[bestj];
       pb[bestj]=temp;
       suma-=bestchange;
       sumb+=bestchange;
       diff=suma-sumb;
   }
   return true;

}

6、输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。如{10,675,23},输出最小数字为1023675。(用伪代码实现)

   //伪代码
   int compare(int A,int B){  
       m = A的位数;
       n = B的位数;
       k = min(m,n);
       for i=[1,k]{
           if a[i]<b[i]
               return -1;
           else if a[i]>b[i]
               return 1;
       }
       // 上一个for循环如果没有return,则说明某个数和另一个数的前部分完
       //全相同,则进行下面的比较
       k = m-n;
       if(k<0){
           for i=[1,-k]{
               if B[i]<B[m+i]
                   return -1;
               else if B[i]>B[m+i]
                   return 1;
           }
       }else{
           for i=[1,k]
               if A[i]<A[m+i]
                   return -1;
               else if A[i]>A[m+i]
                   return 1;
       }
       return 0;
   }