zoukankan      html  css  js  c++  java
  • android学习笔记

    一、基础知识
    android四大组件:Activity,Service,Broadcast Receiver,ContentProvider
    Activity:一个活动界面;
    Service:没有活动界面的后台程序
    Broadcast Receiver:系统广播
    ContentProvider:实现数据共享

    Intent:用于组件之间的沟通
    AVD:Android Virtual Devices 虚拟设备
    (AVD的Device选择3.2*QVGA(ADP2)(320*480:mdpi)屏幕比较合适)
    ADB:Android Debug Bridge 调试工具
    DDMS:Dalvik Debug Monitor Service

    文件目录:
    src:保存java源代码
    gen:保存自动生成的R资源类文件夹
    R.java:java源文件和引用资源之间的一个资源索引类
    assets:保存原始资源文件
    res:保存资源文件,layout保存布局文件,values保存常量值
    string.xml:声明系统用到的字符串常量
    drawable:保存图片等资源
    drawable-hdpi:表示高屏幕密度图片 drawable-mdpi:中等屏幕密度  drawable-ldpi:低级屏幕密度
    AndroidManifest.xml:所有组件必须在该文件中声明

    二、用户界面
    菜单:
    Options Menu(选项菜单)、ContextMenu(上下文菜单)、SubMenu(子菜单)

    常用控件:
    TextView,Button,EditText,ImageView,ProgressBar
    DataPickerDialog、TimePickerDialog、AlertDialog

    常用布局:
    LinearLayout(线性布局)、FrameLayout(帧布局)、TableLayout(表格布局)、
    RelativeLayout(相对布局)、AbsoluteLayout(绝对布局)  、DrawerLayout(抽屉布局)
    FrameLayout:层叠排列,第一个添加的组件放在最底下,最后添加的组件在最上面,
    上一层的会覆盖下一层的控件。

    视图:
    ListView(列表视图)、GridView(网格视图)、Gallery(画廊视图)、WebView(网络视图)
    SurfaceView(动画视图)


    三、Activity
    Activity生命周期:
    OnCreate():创建活动,加载布局      
    onStart():由不可见变为可见
    onResume():变成可与用户交互
    onPause():在系统准备去启动或者恢复另一个活动时候调用?
    onStop():变得不可见
    onDestroy():销毁
    onRestart():重新启动

    onCreate()方法中的 onSaveInstanceState作用:

    方法onSaveInstanceState(...)默认的实现要求所有activity的视图将自身状态数据保存在Bundle对象中。

    Bundle是存储字符串键与限定类型值之间映射关系(键-值对)的一种结构。

    可 通 过覆盖onSaveInstanceState(Bundle savedInstanceState)方 法 , 将一 些 数 据 保存 在 Bundle中 , 然 后在onCreate(...)方法中取回这些数据。

     onSaveInstanceState()被执行的情景:1、用户按下home键时;2、长按HOME键,选择运行其他的程序时;3、锁屏时;4、屏幕方向切换时;

    在每一个运行的应用中, Android都使用任务来跟踪用户的状态。 任务是用户比较关心的activity栈。

    栈底部的activity通常称为基activity。栈顶的activity是用户可以看到的activity。

    用户点击后退键时,栈顶activity会弹出栈外。如果当前屏幕上显示的是基activity,点击后退键,系统将退回主屏幕。
    不影响各个任务的状态,任务管理器可以让我们在任务间切换。

    四、Fragment

    Fragment生命周期:

    onAttach()    //使活动和碎片联系
    onCreate()
    onCreateView()
    onActivityCreated()  //当Activity的onCreate方法返回时调用

    onStart()
    onResume()
    onPause()
    onStop()
    onDestroyView()   //与onCreateView想对应,当该Fragment的视图被移除时调用
    onDestroy()
    onDetach()   //与onAttach相对应,当Fragment与Activity关联被取消时调用

    Fragment的静态使用方法:

    1.在Layout中新建fragment对应的xml文件;

    2.新建类,继承Fragment,重写onCreateView等方法;

    3.在activity的xml文件中,加入对应的fragment控件.

    Fragment的动态使用方法:

    1.创建待添加的碎片实例。
    2. 获取到 FragmentManager,在活动中可以直接调用 getFragmentManager()方法得到。
    3. 开启一个事务,通过调用 beginTransaction()方法开启。
    4. 向容器内加入碎片,一般使用 replace()方法实现,需要传入容器的 id 和待添加的碎片实例。
    5. 提交事务,调用 commit()方法来完成。

    通过fragment来动态加载布局:
    layout/activity_main 布局只包含了一个碎片,即单页模式,而 layout-large/activity_main 布局包含了两个碎片,即双页模式。

    其中 large 就是一个限定符,那些屏幕被认为是 large 的设备就会自动加载 layout-large 文件夹下的布局,而小屏幕的设备则还是会加载layout 文件夹下的布局。


    四、intent

    intent可以实现组件之间的跳转,还可以传递数据,包括action,data,category等.
    1.显式intent在活动之间跳转(记得在AndroidManifest.xml里注册第二个Activity)
    Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
    startActivity(intent);

    2.隐式intent在活动之间跳转(记得在AndroidManifest.xml里注册第二个Activity)
    Intent intent = new Intent("com.example.IntentDemo.ACTION_START");
    startActivity(intent);

    3.打开一个网页
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("http://www.baidu.com"));
    startActivity(intent);

    4.调用系统拨号界面
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:10086"));
    startActivity(intent);

    5.向下一个活动传递数据
    Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
    intent.putExtra("extra_data", "Hello,SecondActivity");
    startActivity(intent);

    五、BroadcastReceiver
    注册广播的方式一般有两种,在代码中注册称为动态注册,在 AndroidManifest.xml 中注册称为静态注册。
    动态注册:
    1.新建类继承BroadcastReceiver,并重写receive();
    2.在Activity的onCreate()里面,实例化IntentFilter,并addAction,然后用registerReceiver()注册;
    3.动态注册的广播接收器一定都要取消注册才行,可以在 onDestroy()方法中通过调用 unregisterReceiver()方法来实现的。
    静态注册:
    1.新建一个类继承BroadcastReceiver,重写onReceive()方法;
    2.在AndroidManifest里面对BroadcastReceiver注册,写出<intent-filter>包含的广播信息;
    3.在AndroidManifest里面用<uses-permission>声明权限;
    3.在Activity里,实例化intent,并用sendBroadcast()发出广播.

    由于广播是使用 Intent 进行传递的,因此可以在 Intent 中携带一些数据传递给广播接收器。

    六、后台服务
    每一个服务都需要在 AndroidManifest.xml文件中进行注册才能生效, Android四大组件共有的特点。
    bindService(绑定服务)其实就是让服务执行完后,返回一些数据给启动它的组件比如activity。
    Service生命周期:
    startService(): onCreate()-->onStartCommand()-->onDestroy().
    bindService():  onCreate()-->onBind()-->onUnbind()-->onDestroy().

     服务中的代码都是默认运行在主线程当中的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现

    ANR(Application Not Responding)的情况。应该在服务的每个具体的方法里开启一个子线程,然后
    在这里去处理那些耗时的逻辑。
    IntentService:异步的、会自动停止的服务

    通知信息(notification)

    如果服务需要与用户进行信息沟通, 通知信息(notification是个不错的选择。通知信息是指显示在通知抽屉上的消息条目,用户可向下滑动屏幕读取。
    为发送通知信息,首先需创建一个Notification对象。Notification需使用构造对象完成创建。 Notification应至少具备:
    首次显示通知信息时,在状态栏上显示的ticker text
    ticker text消失后,在状态栏上显示的图标;
    代表通知信息自身,在通知抽屉中显示的视图;
    用户点击抽屉中的通知信息,触发PendingIntent
    完成Notification对象的创建后,可调用NotificationManager系统服务的notify(int,Notification)

    七、异步消息处理机制:

    在主线程 (UI线程)中不允许进行耗时的操作。(比如网络操作在主线程进行,就会报NetworkOnMainThreadException异常)
    而Android 不允许在子线程中进行 UI 操作的.但是有些时候,我们必须在子线程里去执行一些耗时任务,然后根据任务的执行结果来更新相应的 UI 控件

    Message、Handler、MessageQueue、Looper
    首先需要在主线程当中创建一个 Handler 对象,并重写
    handleMessage()方法。然后当子线程中需要进行 UI 操作时,就创建一个 Message 对象,并
    通过 Handler 将这条消息发送出去。之后这条消息会被添加到 MessageQueue 的队列中等待
    被处理,而 Looper 则会一直尝试从 MessageQueue 中取出待处理消息,最后分发回 Handler
    的 handleMessage()方法中。由于 Handler 是在主线程中创建的,所以此时 handleMessage()方
    法中的代码也会在主线程中运行,于是我们在这里就可以安心地进行 UI 操作了。

     八、存储的持久化
    数据持久化主要分为:文件存储、SharedPreference、Sqlite数据库存储
    1、文件存储:
    其实所用到的核心技术就是 Context类中提供的 openFileInput()和 openFileOutput()方法, 之后就是利用 Java
    的各种流来进行读写操作就可以了。
    2、SharedPreferences存储:
    a. 调用 SharedPreferences 对象的 edit()方法来获取一个 SharedPreferences.Editor 对象。
    b. 向 SharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用
    putBoolean 方法,添加一个字符串则使用 putString()方法,以此类推。
    c. 调用 commit()方法将添加的数据提交,从而完成数据存储操作。
    示例如下:
     SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
     editor.putString("name", "feng");
    读取SharedPreferences的数据:
    SharedPreferences 对象中提供了一系列的get方法用于对存储的数据进行读取.
    get 方法都接收两个参数,第一个参数是键,传入存储数据时使用的键就可以得到相应的值了,
    第二个参数是默认值,即表示当传入的键找不到对应的值时,会以什么样的默认值进行返回。
    示例如下:
    SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);
    String name = pref.getString("name", "");
    也可以使用默认的SharedPreferences
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    String name=prefs.getString("name", "");

    3、SqLite数据库存储
    借助SQLiteOpenHelper实现数据存储。SQLiteOpenHelper 是一个抽象类,想要使用它的话,就需要创建一个类去继承它。
    SQLiteOpenHelper 中有两个抽象方法,分别是onCreate()和 onUpgrade(),重写这两个方法,然后分别在这两
    个方法中去实现创建、升级数据库的逻辑。

    还有一个构造方法,如下所示:

    public SQLiteTest(Context context, String name, CursorFactory factory,
                int version) {
            super(context, name, factory, version);
        }
    另外的,getReadableDatabase() 和getWritableDatabase()。这两个方法都可以创建或打开一个现有的数据库(如果数据库已存在
    则直接打开,否则创建一个新的数据库) ,并返回一个可对数据库进行读写操作的对象。不
    同的是,当数据库不可写入的时候(如磁盘空间已满)getReadableDatabase()方法返回的对
    象将以只读的方式去打开数据库,而 getWritableDatabase()方法则将出现异常。
    查询数据:
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    Cursor cursor = db.query("Book", null, null, null, null, null,null);
    if (cursor.moveToFirst()) {
        do {
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String author = cursor.getString(cursor.getColumnIndex("author"));
            int pages = cursor.getInt(cursor.getColumnIndex("pages"));
            double price = cursor.getDouble(cursor.getColumnIndex("price"));
                        } while (cursor.moveToNext());
                    }
    cursor.close();
    插入数据:
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("name", "The Da Vinci Code");
    values.put("author", "Dan Brown");
    values.put("pages", 454);
    values.put("price", 16.96);
    db.insert("Book", null, values);            

     修改数据:

    SQLiteDatabase db = dbHelper.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("price", 10.99);
    db.update("Book", values, "name = ?",new String[] { "The Da Vinci Code" });

     删除数据:

    SQLiteDatabase db = dbHelper.getWritableDatabase();
    db.delete("Book", "pages > ?", new String[] { "500" });

    九、网络编程

    URL(Uniform Resoure Locator),统一资源定位符,是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址

    URI(Uniform Resource Identifier),统一资源标识符,是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对任何互联网的资源通过特定的协议进行交互操作
    在Android上发送Http请求的方式一般有两种:HttpURLConnection和HttpClient
    1、HttpURLConnection,一般先实例化URL对象,并传入目标的网络地址,调用一下openConnection().
    GET 和 POST。GET 表示希望从服务器那里获取数据,而 POST 则表示希望提交数据给服务器。
    再调用 getInputStream()方法就可以获取到服务器返回的输入流了, 剩下的任务就是
    对输入流进行读取.最后调用 disconnect()方法将 HTTP 连接关闭掉.
    代码如下所示:
    private void sendRequestWithHttpURLConnection() {
           // 开启线程来发起网络请求
           new Thread(new Runnable() {
           @Override
           public void run() {
           HttpURLConnection connection = null;
           try {
           URL url = new URL("http://www.baidu.com");
           connection = (HttpURLConnection) url.openConnection();
           connection.setRequestMethod("GET");
           connection.setConnectTimeout(8000);
           connection.setReadTimeout(8000);
           InputStream in = connection.getInputStream();
           // 下面对获取到的输入流进行读取
           BufferedReader reader = new BufferedReader(new
           InputStreamReader(in));
           StringBuilder sb = new StringBuilder();
           String line;
           while ((line = reader.readLine()) != null) {
                  sb.append(line);
           }       
           Message message = new Message();
           message.what = SHOW_RESPONSE;
           // 将服务器返回的结果存放到Message中
           message.obj = sb.toString();
           handler.sendMessage(message);
           } catch (Exception e) {
                  e.printStackTrace();
           } finally {
                  if (connection != null) {
                  connection.disconnect();
           }
          }
        }
     }).start();
    }
    2、HttpClient,HttpClient 是一个接口,因此无法创建它的实例,通常情况下都会创建一个 DefaultHttpClient 的实例.
    接下来如果想要发起一条 GET 请求,就可以创建一个 HttpGet 对象,并传入目标的网络地址,然后调用 HttpClient 的 execute()方法;
    如果是发起一条 POST 请求需要创建一个 HttpPost 对象,并传入目标的网络地址,然后通过一个 NameValuePair 集合来存放待提交的参数,并将这个参数集合传入到一个
    UrlEncodedFormEntity 中,然后调用 HttpPost 的 setEntity()方法将构建好的 UrlEncodedFormEntity传入,最后调用 HttpClient 的 execute()方法,并将 HttpPost 对
    象传入即可。
    执行 execute()方法之后会返回一个 HttpResponse 对象, 服务器所返回的所有信息就会包含在这里面。
    通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了。

    private void sendRequestWithHttpClient() {
    new Thread(new Runnable() {
    @Override
    public void run() {
    try {
      HttpClient httpClient = new DefaultHttpClient();
      HttpGet httpGet = new HttpGet("http://www.baidu.com");
      HttpResponse httpResponse = httpClient.execute(httpGet);
      if (httpResponse.getStatusLine().getStatusCode() == 200) {
      // 请求和响应都成功了
      HttpEntity entity = httpResponse.getEntity();
      String response = EntityUtils.toString(entity,"utf-8");
      Message message = new Message();
      message.what = SHOW_RESPONSE;
      // 将服务器返回的结果存放到Message中
      message.obj = response.toString();
      handler.sendMessage(message);
        }
       } catch (Exception e) {
    e.printStackTrace();
     }
    }
    }).start();
    }

     

  • 相关阅读:
    Golang 学习权威网站
    iOS多线程GCD的使用
    iOS 开发 nonatomic 和 atomic
    iOS证书配置与管理
    iOS pthread
    NSTimer 不工作 不调用方法
    iOS开发者学习Flutter
    Xcode如何打开Archives打包界面?
    iOS 12.1 跳转页面时 tabBar闪动
    支付宝
  • 原文地址:https://www.cnblogs.com/expiator/p/5649230.html
Copyright © 2011-2022 走看看