Android 应用开发入门

1.框架:
1)Linux kernel
2)Libraries (C/C++编写) : 为 GUI , Android系统服务提供实现。
   有 Surface Manager (不需要GUI干涉的视图), OpenGL, SQLLite, WebKit, libc
3)Android Runtime  : java虚拟机Dalvik , 核心类库
4)Application Framework: java编写的Android框架和GUI.
   有Activity Manager(应用程序最小单元), Windows Manager, Package Manager, Telephone Manager(应用处理器[即界面内容]和调制解调器), View System(每个控件都是View), Resource Manager,Locaton Manager(GPS),Notification Manager, XMPP Service(应用层通信协议).
5)Application : 应用程序。 

2. 开发分类:
Linux kernel(驱动 并且要与 Library协同工作),  Library(调用驱动), Application Framework(对Framework扩展:调用Library), Application.

3.开发应用程序:
Eclipse插件ADT : ... 及 AVD ...
Android SDK : 设置SDK路径.


4. Hello word
Create > Android Application
Project Name : 项目名称
Application Name : 应用程序名称


5.基础
Android的4种程序片段:
Activity: 有图形界面的最小执行单元,用户可与之交互。
Service: 无图形界面的最小执行单元, 一般在后台执行一些任务(如下载、播放音乐)。
Receiver: 响应系统广播消息的独立执行单元。
Provider: 应用程序内部定义一个Provider服务, 其它应用程序可以访问这个Provider, 从而读写相关的文件或数据。

一个Activity有且只有一个Window, 每个Window有且只有一个ViewGroup, 每个ViewGroup 可有多个View或ViewGroup.

消息流程:
Window和View管理器是GUI的核心,GUI内部消息传递流程:当系统检测到用户消息后(如触摸), 系统会把此消息传递

给当前Activity, Activity 再把此消息传递给Window, Window管理着ViewGroup的界面位置信息, 因此知道把消息发

送给哪个View或ViewGroup, 对应的View或ViewGroup会响应并处理不同的用户消息。

Android程序可从任意一个Component处启动。

Activity的启动方式有多种 , 如startActivity(Intent intent)
启动顺序:onCreate(); onStart(); onResume(); onPause(); onStop();

注意,Activity启动是异步的,当调用startActivity后, 系统不是立即执行新的Activity, 而是由Activity Manager调度, 在startAcitvity返回后, 先中止正在运行的Activity, 再启动新的Activity. 

Activity 的  onCreate() :   setContentView( R.layout.main ), 用来把一个ViewGroup设置为该Activity所用的界面。

@: 表示引用, 如  @string/hello   表示引用 value中的string.xml 中的hello.

@+:表示引用和添加。

颜色: "#ARGB"   , A表示通光度。

 Manifest.xml : manifest(货单,清单的意思), 展示程序片断及启动条件,命名,或本程序许可权。
其中包括:
<activity />, <service />, <provider />, <receiver />

Android片断运行的可能实现:每个Application可能对应了多个可执行程序。

Android 与 Windows程序区别: 片断运行, 每个application使用不同linux user id.


5.Java 语法在 Android中使用.
1) interface: 用于接口(服务端调用, 客户端实现)。
    abstract class: 用于继承(继承,重写)。
2) for : fro( int age: ages )
3) 其它工具类: map
4) synchronize : 同上,用于函数,对象。( chronic慢性的, sync 同步)( asychronize异步)
5)new : 没用new分类的数据都是从栈中分配,用new的都是从堆中分配。

 

 


6. 用户接口:

1)布局: Activity( Window( ViewGroup(  View, ..., ViewGroup  ) ) )
    LinearLayout,RelativeLayout,FrameLayout,TableLayout 都是ViewGroup的子类。
    TextView, EditView, Button, ImageView, ImageButton, CheckBox, ToggleButton(开关), RadioButton,RadioGroup(有orientation属性,有checkButton属性), RatingBar(带评选的进度条), ScrollView( 内部只能有一个View ),    

    其它视图:  android.widget.*
    为View指定属性:可用 style="@style/style_name"
   
    视图大小与位置:
    margin 与 padding ...
    对于ViewGroup是layout的根结点时, marginLeft与marginTop分别等同于marginRight, marginBottom. 即Android对页面的布局总是从左上角(0,0)处开始的, 也就是根节点必须从(0,0)开始绘制。注意, 根ViewGroup既有marginLeft和marginRight时, 两者取其大,且与顺序无关。
    对齐方式:gravity, 对View来讲,用于指定其包含内容的对齐方式; 对ViewGroup来讲,用于指定其包含的View, ViewGroup的对齐方式。
   
    动态创建View和ViewGroup:
       a. View不支持addView()方法, ViewGroup可以用来添加ViewGroup或View.     Activity有setContentView(R.layout.main)方法, 也有findViewById()方法,且findViewById只从其当前的ContentView中寻找该id的View.
          LinearLayout ll=new LinearLayout( this [即当前Activity] );
          ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParam.Fill_PARANT,xx.FILL_PARANT);
          ll.setLayoutParams( params );
       b. 利用LayoutInflater(布局泵)来添加一个xml文件(如layout_2.xml)描述的ViewGroup.
            LayoutInflater inflater = this.getLayoutInflater();
            ViewGroup v = (ViewGrooup)findViewById( R.id.main_sub_layout );
            inflater.inflate( R.layout.layout_2, v);

        Activity的setContentView方法: 该方法是设置Activity的内部ContentView的方法,Activity任何时刻只有一个ContentView。

    常用的ViewGroup( layout ):
         LinearLayout : 其另一个属性 weight, 用于指定其占用剩余空间的权重。(????)
         RelativeLayout : 按照父兄位置来布局,不存在orientation属性。 layout_below, layout_toLeftOf, ...         ...( 可参见RelativeLayout.LayoutParams)
        TableLayout : <TableRow>, android:stretchColums(合并单元格), android:collapseColums(消除指定的列)
         FrameLayout : 所有View位置总是从屏幕左方开始的。 (android:visibility可控制各个view的可见性。)
        WebView : 网页视图, 内嵌浏览器。
AssetManager am;
       am = getAssets();
       String webcode="";
  try {
      InputStream is = am.open("a.html");
      int size = is.available();
      byte[]buf = new byte[size];
      is.read(buffer);
                    webcode = buf.toString();
       webcode=new String(buf, "gb2312");
      is.close();
         }catch(IOException e){
      Log.e("fillread", "read html error!");
  }      
  WebView web = (WebView)findViewById( R.id.webView );
  web.loadDataWithBaseURL(null, webcode, "text/html", "utf-8", null);
 
2)事件响应
 内部类可以使用外部类的成员变量。
 内部接口...
 View内部的数据处理:(根据用户消息进行运算), (调用接口), 绘图。
 OnClickListerner l = new OnClickListener(){
   public void onClick( View v ){
    TextView tv=(TextView)findViewById(
   }
  }

3)菜单
 a.选项菜单(OptionMenu)
     Activity有onCreateOptionMenu(Menu)和onSelectOptionItem(Item)
     程序创建、文件创建. 
 b.上下文菜单(ContextMenu)
     当长屏幕时, 会发生onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)方法调用(注意它是Activity的方法,只能通过v.getId()来区分当前是长按在哪个View上面, 从而生成相应的上下文菜单)。
      当关闭时, 会有onCloseContextMenu发生调用。
     当选择时, 会有onContextItemSelected(MenuItem item).
     另外要注意的是,当同一位置父子View都有ContextMenu时( 即 case ID1: menu.add(); break; case ID2: menu.add(); break;), 由于它们共用同一个ContextMenu, 所以两个add()都会执行,从而不是我们想要的结果。为了处理这种情况, 可以在添加menuItem之前,执行menu.hasVisibleItems()作一个检测。
 c.子菜单(SubMenu).
 d.单选与复选菜单.
     单选菜单, 要把需要互斥的菜单项放在一个组中(组id相同), 其次,使用setGroupCheckable来设置其选择状态与是否互斥。
 e.使用xml文件来描述菜单.
     <menu>, <item>, <group>
4)各种对话框( 稍后 )
Dialog是由Dialog Manager管理。
showDialog(int id), dismissDialog(int id), removeDialog(int id);
onCreateDialog(int id), onPrepareDialog( int id , Dialog dialog)[对话框存在的话,在显示之前可对其内容进行处理];
a. 提示对话框 AlertDialog
 AlertDialog.Builder builder = new ...;
 builder.setSositiveButton( ... ).setNegativeButton( ... ).setTitle( ...  ).setMessage( ... );
 AlertDialog alert = builer.create();
 builder.setItems( ... );
b. 进度对话框 ProgressDialog
c. 日期时间对话框: DatePickerDialog, TimePickerDialog
d. 自定义对话框:
 方法一: 基于AlertDialog, 调用SetView来添加任意视图。
 方法二:基于Dialog, 设置其 contentView, 并且自定义事件处理。
 public final View findViewById (int id) : 可以在ViewGroup内部寻找对应ID的view.

5)绑定视图与数据(复杂的视图如List, Grid, Tab)
Adapter View(View利用Adapter来操作显示的内容) 与 Adapter(提供操作数据的接口)
a. 下拉列表Spinner :
 
b. 格子视图GridView:
c. 相册Gallery:
d. 标签页TabWidget:
e. 列表视图ListView:

6)自定义View

 ( ??? ????)

 
7. Intent 与 Intent Filter   
    四种程序片断: Activity, Service, Brocast Receiver, ContentProvider.
    除了ContentProvider之外, 其它四种都是通过Intent启动的。
    Intent 是一种数据结构, 包含了想要启动的程序片断的相关信息,由Application Framework来接收Intent, 并判断其属于哪种片断, 并用相应的 Activity[Service|Receiver] Manager 来启动对应的片段。
    启动程序片段的方式:显示(指明程序片断) 或 隐式(Intent 仅指明需要的功能, 一般AndroidManifest.xml的Intent Filter就是告诉系统自己的功能)。
    Intent数据结构:(片断名称Component Name),Action,Data,Category,Exras,Flags
    Action测试: intent.setAction( <action android:name = "xxx.xxx.xxx" /> );
     在<intent-filter>中, 有android:icon, android:lable, android:priority, <action>指定action名字,<category>指定类别(?????什么用???)。
    Data测试。。。

8.使用Activity
1)  应用程序只有一个Context对象,
    一个Activity只有一个Window,可以在Activity中使用setContentView()来给Window设置一个具体的视图。
      Window win = getWindow();
      win.setTitle("通过程序设置边框.");
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  //设置成全屏方式,则上方状态栏也会隐藏。
    若旧Activity部分可见,则它会被调用onPause(), 然后返回时调用onResume().
    若旧Activity不可见,则它会被调用onStop(), 在返回时,它的onRestart()会被调用,并从onStart()开始执行。
    注意上述说明中, 还会有特例。

    启动Activit:
 直接;
 使用菜单: 在onCreateOptionsMenu()中使用 m_item.setIntent(this, Xxx.class)), 在onOptionsItemSelected()中使用super.onOptionsItemSelected(item);
 注意:两个方法, 一个是先调用 super.onCreateOptionsMenu()再加MenuItem, 一个是先判断ID再调用super.onOptionsItemSelected(item);
   
2) 使用小工具Widget
    用途:a通知与提醒: 网络类,本地类; b.作为快速入口。
    原理:Widget管理器定期向Widget发送消息。
    Widget对象的组成:a.界面描述。b.响应特征(如多长时间收到一次)。c.实现对数据处理, 即AppWidgetProvider类,实际上是基于Broadcast Receiver程序片断的。也就是说AppWidgetManager是一个发送广播的服务,AppWidgetProvider都可以收听该广播消息。
    结构:在Manifest.xml中声明程序提供的Widget, 并指向 WidgetInfo.xml, 在Widget layout.xml中定义界面。
    创建Widget:
          a.在Manifest.xml中创建一个 <receiver>标签,action为 andorid:name="....

action.APPWIDGET_UPDATE"
            android:resource指定info文件。
   b.res/xml下创建 info.xml, 定义其最小宽高,更新时间,初始布局文件layout/mymusic_widget.
          c.在layout下创建mymusic_widget.xml, 描述其布局。
   d. 在src 目录下创建Widget实现文件, MyMusicWidget extends AppWidgetProvider{ opUpdate(Contextcontext, AppWidgetManager manager, int [] appWidgetIds){ ... } }    
    Widget的函数调用情况:
        onUpdate() : 每次添加到桌面时,及通知周期来临。       
        onEnable() : 每一次添加时。
        onDisable(): 最后一个实例被删除。
       onDelete() : 每删除一个时。
 
    在Widget中启动Activity:
       在onUpdate()中有如下代码:
 ComponentName serviceName = new ComponentName( context, MusicPlayer.class ); //组件名。
 RemoteViews views = new RemoteViews( context.getPackageName(), R.layout.mymusic_widget );
 // RemoteViews 是创建一个外部程序可以访问的视图对象, 因为Widget本身是在桌面中。
 Intent intent = new Intent();
 intent.setComponent( serviceName );
 
 PendingIntent pendingIntent;  //挂起的Intent.
 pendingIntent = PendingIntent.getActivity( context, 0, intent, 0);
 // 获取一个启动Activity的PendingIntent对象.
 views.setOnclickPendingIntent( R.id.widget_button, pendingIntent);
 // 当此事件发生时, 把挂起的事件执行。
 appWidgetManager.updateAppWidget(appWidgetIds, views);
 // 让WidgetManager来管理属于桌面的View.

    问题:Widget是在桌面面上显示,由WidgetManager对其管理(消息处理等等 ) ??
    另外,RemoteViews对象不能获取Widget视图中的值,故,想用Widget做一个桌面上的快速搜索的工具都不能完成

。。。
  
4)使用Notification
 Notification Manager .... 可以通过 getSystemService()来获得该管理器对象。
 创建一个通知:获取NotificationManager对象, 创建一个Notification对象, 获取应用程序的上下文getApplicationContext(), 创建一个PendingIntent, 设置Notifi的参数, 然后用NotificationManager的notify方法来生成一个通知。
 可在notification.setLatestEventInfo()中设置可在通知窗口中启动的Activity.

5)保存存活状态
 Activity的onCreate(Bundle )及onRestoreInstanceState(Bundle )可用于在启动和销毁Activity时恢复和保存程序的数据。注意,系统一般都会保存界面元素的值,故只需要保存程序的各种数据值。

6)Activity之间数据传送:
 使用 startACtivityForResult():
 a.旧Activity使用startActivityForResult()来启动新Activity, 并且在onActivityResult中获取新

Activity返回的数据。
 b.新Activity可以使用intent.getExtras()来获取旧Activity传送过来的数据, 并且,可以setResult()返回数据及返回码。

7) Activity 与 Task
    任务Task是一个栈,默认情况下,当应用程序X调用X或Y的Activity时,它们会在同一个Task内,即在同一个Stack内。按返回键时,是返回到上一个Activity.
    设置某个Activity在一个新栈中:a.可以通过intnet.setFlag()的方法, b.可以在Activity中使用android:launchMode="singleTask"属性。


9.使用Service
 Service 启动方式:startService() 与 bindService().
 如果Service与Client同在一个应用程序内, 默认情况下, 它们在同一个进程、同一个线程内运行。
 
 创建Service:
 使用AIDL(接口定义语言), 定义服务接口。
( ???? ????) 

10.使用Broadcast Receiver
 发送接收.
 Receiver 没有界面,并且周期非常短,只有在执行onReceive()方法中才有效,故在其中不能执行具有回调功能的异步函数。因为当异步函数调用时,Receiver已经结束。
 广播消息分类:系统已经定义的 与 自定义的广播消息。
 接收消息分类:静态接收,即在安装时,就声明其可以接收的消息; 动态接收,在接收前,使用registerReceiver()方法向系统注册一个Receiver.

 异步广播sendOrderedBroadCast() 与 异步广播sendBroadCast()。
1) 静态创建Receiver
    manifest.xml中:
 <receiver android:name=".bootDisplayReceiver">   //系统启动后的Receiver
 <intent-filter>
  <action android:name = "android.intent.action.BOOT_COMPLETED" />
 </intent-filter>
 </receiver>
    src目录下:
 public class bootDisplayReceiver extends BroadcastReceiver}
  public void onRecevie(Context context, Intent intent){
   //可以启动一个Activity.或进行其它其它的操作。
  }
 }
2)动态创建Recevier
    一般在onResume()中进行registerReceiver(), 在onPause()中unregisterReceiver(); 注意的是,如果程序结束后没有Receiver, 那么该Recevier会一直处理接收广播消息,直到该程序的Context被销毁
    例:a.在继承自BroadcastRecevier的类中,重写onReceive()。 
            b.Activtity中,在onCreate()里面创建一个IntentFilter并增加Action, 并且创建一个Receiver   在onResume()里注册,在onPause()里注销。
    注意:这里的注册是使用实例(...一般的注册都是使用例),而不是类名(...在Intent里使用类名).
  
    另一个用途:Service与Activtiy通信,Service中建一个Receiver, 接收Activity的广播消息,当接收到消息时,执行Service的相应方法。

    
11.使用Content Provider
 两方面:一是使用别人的Provider, 二是提供一个Provider供别人使用。
 Provider类似于Windows系统中的服务。
1) 使用另人的Provider.
 方法1.使用 getContentResolver()返回的 ContentResolver对象的query()来操作Provider。
 方法2.使用 Activity的manageQuery()来使用Provider, 它更灵活,可以在onpause(),onStart()中自动释放或重新获取cursor指针。
 query( Uri uri, String[]projection, String selection, String[]selectionArgs, String sortOrder);
 其中, uri指: Content://+包名+Provider名+/表名+/id值, projection 指返回的列名, selection指 where 语句,selectionArgs指 where中的点位符?代表的值, sortOrder指order by 后面的列。 
 在返回的Crusor对象中,可以使用 mCursor.moveToFirst(), mCursor.getColumIndex(People.NAME), mCursor.getString( index );
 注意:在urss-permission中加上 andorid.persmission.READ_CONTEACTS.

 修改Provider...
2) 定义自己的Provider
 a.设计存储:一般情况下使用数据库存储,可以直接利用返回的Cursor对象。
 b.创建Provider类,该类必须基于 Content Provider类。
 c.在Manifest.xml 文件中声明该Provider, 声明权限。 


12.资源文件
 assets(资产)目录下文件以字节流形式使用。
 res 目录下的目录命名都是固定的。
 资源类型:编译前(使用xml描述), 编译后(使用R.xxx.yy 描述).
 颜色资源(values),字符串资源(values)
 点阵图资源(drawable),单色图资源(drawable),动画(anim),菜单(menu),布局(layout)
 自定义视图(values)
 元数据文件(raw)
 样式( values)
 主题( values)
 
 assets管理器: AssetManager am = getAssets();

 Android环境参数表:屏幕方向,键盘,方向键类型,屏幕分辨率??。

13.存储
 系统文件夹: data( ./app第三方程序,./data/所有程序的私有数据), sdcard(文件。。。), system( ./app系统内置的应用程序)。 
 Android本地存储有3种方式: 文件存储,数据库,参数化存储(存储在.xml中). 它们都是私有的.
 故为了使不同应用程序间共享数据, 只能通过Provider来提供。
 文件路径:Uri格式为 file:///xxx/xxx/xxx.xxx;  String格式为 /xxx/xxx.xxx
 程序的私有文件: 在  data/data/xxx.yyy/ 下,一般有3个私有目录: files(保存创建的文件, 可以用标准java IO访问), shared_prefs( xml文件 ), database,  同时也可建立其它目录。
1) 文件存储
 读取私有文件夹files下的文件: context.openFileInput()和openFileOutput().
 读取其它文件夹下的文件:使用标准的 java IO.
 
 遍历文件夹:File flist = new File("/sdcard/"); mFileList = flist.list();
 读写文件:context.openFileInput() 与 context.openFileOutput()
2) 数据库存储
 SQWLiteOpenHelper, SQLiteDatabase
 数据库的存储:a.设计数据表; b.为每个表设计一个Java类(适配层); c.为每个Java类定义一个基于SQLiteOpenHelper的内部类,提供onCreate()和onUpdate()两个方法。d.在每个Java类内部添加一些应用层使用的函数, 或者直接使用SQLiteDatabase包含的方法; e.在每个Java类中, 把数据更的名称定义为常量,便于访问。
 
3) 参数存储
 SharedPreferences


14.多线程
 Android的多线程是基于Linux本身的多线程机制,而多线程之间的同步又是通过Java本身的线程同步。
 线程在系统中占用不同的地址段。
 Android系统中,是循环取消息(Looper)、接着处理消息(Handler)。
 Android中,一个Activity就是一个线程,多个Activity之间的切换是在同一个线程中。
 新建一个Thread对象一般需要实现两个函数: a.构造函数(传递context); b.run(), 停止线程,不能用

destroy()或stop(), 可用一个变量,通过判断自行结束。

1) Thread 与 Runable : Runable 只是一个接口,不含线程实现,故只能使用Thread的静态方法,它一般只作为一个参数传递。
2)Thread 与 Service的区别:

3) Handler 与 Looper
    Handler 用于处理线程中的消息队列, 它与线程相关联,有 handler.handleMessage() 及

handler.sendMessage() , postXXXX()[用于把一个Runnable对象发送到消息队列]。
    注意:只要有handler句柄,就可以跟它所属的线程发送消息。
   
    Looper: 相当于 run()方法中的一个大循环, 接收消息,并使用handler进行处理。
 run(){
     Looper.prepare(); //新建一个looper对象。
     Handler handler = new Handler(){ };
     Looper.loop();  //大循环,在其中接收消息,并且使用本线程的handler来处理。 
 }
4) 线程同步
 synchronize; 对于方法或代码段。
 wait(),notify(), notifyAll(); //对于对象。
 join()/interrupt();   //对于线程。  
   

15.系统安全

 程序签名: 程序签名使用 <公匙,私匙>, 并且使用私匙加密程序,并且只能使用对应的公匙来解密程序。
 安全调用, 分为5种:
 a.系统功能调用:电话,短信,蓝牙,网络。
 b.启动Activity: 设置允许其它程序启动。。
 c.Broadcast Receiver发送与接收:sendBroadcast()时可指定谁才可以接收我发出的消息,对Receiver来讲指定"谁才能给我发送消息".
 d.读写Content Provider.  "只有拥有许可权的程序才能访问我所提供的内容。"
 e. 启动Service. 设置可以启动该Service的程序。
 

16.Manifest.xml

 包含的内容:
 程序包名。
 程序片断。
 许可权限。
 最小API版本。
 外部库文件。


17.多媒体与网络
音乐:MediaPalyer
视频:MediaPlayer + Surface
录音:MediaRecorder
Surface原理: GUI通过SurfaceView操作Surface, 应用程序可以通过SurfaceHolder来操作Surface。
 Activity中:
  //设置全屏
  this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  //显示自定义的SurfaceView视图
  setContentView(new MySurfaceView(this));
  setContentView(new MySurfaceView(this));
 MySurfaceView中:
  MySurfaceView extends SurfaceView implements Callback, Runnable
  在surfaceCreated(SurfaceHolder holder)中创建一个线程。
  public void run() {
  while (flag) {
   long start = System.currentTimeMillis();
   myDraw();  // 在cavas中绘图。
   logic();
   long end = System.currentTimeMillis();
   try {
    if (end - start < 50) {
     Thread.sleep(50 - (end - start));
    }
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 } 
游戏开发:surface, 多线程.
网络:Socket, Http, 电话/短信开发。

18.调试
DDMS: 用于与虚拟机进行数据交换。
ADB :
DDMS <> Device Monitor Service <> ADB.
DDMS <> VM Monitor <> VM.

真实设备与虚拟器上有( App/VM, VM Debugger, adb daemon ).

emulator -avd  my_avd1
emulator -avd  my_avd2
// 可启动多个模拟器。
ddms : 单步调试,文件夹濒临,截屏,制件Emulator(包括地理位置,短信,电话模拟).
adb : 安装应用程序。 也可使用 adb kill-server 停止adb服务,并关闭Emulator.
Logcat : 类似于printf(), Log.i(info), .d(debug),  .w(warning)   .e(error)

为工程添加jar包:
 若jar包不捆到apk中,则需要把 jar包放在设备固定文件夹中,否则Dalvik VM找不到,而这种方法只有手机出厂时完成。
 所以jar包都一般都捆绑到apk中。
 AddLibrary 与 AddJar : 添加库在打包时不会打包进 apk中, 而添加jar时,会打包进apk中。


19.应用开发实例
(android: QQ服务端、客户端实现)


20.游戏开发实例
(andorid: 小型单机或网络游戏)   

 

 

Eclipse 快捷键:???

 

帮助文档:
android-sdk-windows\docs

  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值