第二行代码读书总结加笔记

来源:互联网 发布:各种编程语言的用途 编辑:程序博客网 时间:2024/05/21 10:12

第一章

一、Android系统架构

          Linux内核层:为Android设备的各种硬件提供了底层的驱动,如:显卡驱动、音频驱动、照相驱动、蓝牙驱动、WI-FI驱动、电源管理等;

         系统运行库层:通过一些C/C++库来为Android系统提供了主要的特性支持.

         应用框架层:提供了构建应用程序时可能用到的各种API;

         应用层:所有安装在手机上的应用程序都属于这一层;

二、搭建开发环境

  http://www.androiddevtools.cn/(软件下载网址)

  JDK

  Android Studio

  Android  SDK

项目目录结构
1、.gradle和.idea(自动生成,无需关心);
2、app:项目中的代码、资源等内容几乎都是放置在这个目录下的;build和外层的build类似,主要包含一些编译时自动生成的文件;libs:项目中使用到的第三方的jar包,需要将这些jar包都放在libs目录下,放在这个目录下的jar包都会被自动添加到构建路径里去;androidTest:编写Android Test 测试用例,可以进行一些自动化测试;java:放置Java代码的地方;res:项目中使用到的所有图片、布局、字符串等资源都要存放在这个目录下。AndroidManifest.xml:你整个Android项目的配置文件,你程序中定义的所有四大组件都需要在这个文件里注册,另外还可以在这个文件中给应用程序添加权限声明;test:用来编写Unit  Test测试用例,对项目进行自动化测试的另一种方式;.gitignore:将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似;app.iml: IntelliJ  IDEA项目自动生成的文件;build.gradle:app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置;proguard-rules.pro:指定项目代码的混淆规则;
3、build:编译时自动生成的;
4、gradle:包含gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地缓存情况决定是否需要联网下载gradle;
5、.gitignore:这个文件是用来将指定的目录或文件排除在版本控制之外的.
6、build.gradle:这个文件是全局的gradle构建脚本.1.3.6详解build.gradle文件;
7、Doctor.iml:iml文件是所有IntelliJ  IDEA项目都会自动生成的一个文件,Android Studio是基于IntelliJ  IDEA开发的,用于标识这是一个IntelliJ  IDEA项目;
8、gradle.properties:这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本;
9、gradlew和gradlew.bat:这两个文件是用来在命令行界面执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的
10、local.properties:这个文件用于指定本机中Android SDK路径,通常自动生成的;
11、setting.gradle:这个文件用于指定项目中所有引入的模块。
12、External Libraries

三、详解项目中的资源

    Res目录;所有以drawable开头的文件夹都是用来放图片的,所有以mipmap开头的文件夹都是用来放应用图标的,所有以values开头的文件夹都是用来放字符串、样式、颜色等配置的,layout文件夹是用来放布局文件的.更多的时候美工只会提供给我们一份图片,这时把 所有图片都放在drawable-xxhdpi文件夹下就好了.

四、详解build.gradle文件

        不同于Eclipse,Android Studio是采用Gradle来构建项目的.Gradle是一个非常先进的构建工具,它使用了一种基于Groovy的领域特定语言(DSL)来声明项目设置,摒弃了传统基于XML(如Ant和Maven)的各种烦琐配置.Android项目中两个build.gradle文件对构建Android  Studio项目都起到了至关重要的作用;
项目外层目录下的build.gradle(全局的项目构建配置)文件:jcenter代码托管仓库,声明了jcenter()配置之后,我们可以在项目中轻松引用任何jcenter上的开源项目. 声明了classpath 'com.android.tools.build:gradle:2.2.2'配置表明我们使用Gradle来构建Android(Java、C++等)项目;
项目内层:看看Doctor项目中的build.gradle文件,Android Studio项目中一共有三种依赖方式:本地依赖(可以对本地的Jar包或目录添加依赖关系)、库依赖(可以对项目中的库模块添加依赖关系)和远程依赖(可以对jcenter库上的开源项目添加依赖关系).


第二章


一、在活动中使用Menu

res—>menu—>main布局
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/add_item"
        android:title="=Add" />
    <item
        android:id="@+id/remove_item"
        android:title="Remove" />
</menu>  
一个简单的demo:
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.add_item://实现相应的功能
                break;
            case R.id.remove_item://实现相应的功能
                break;
            default:
        }
        return true;
    }

二、Intent

Intent一般可被用于启动活动、启动服务以及发送广播等情景;
Intent分为:显式和隐式两种;
隐式:(1)注册
<activity android:name=".activity.UpdateSoftActivity">
    <intent-filter>
       <action android:name="com.example.activitytest.ACTION_START"/>
         <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
(2)使用

Intent intent = new Intent("com.example.activitytest.ACTION_START");
startActivity(intent);

每个Intent只能指定一个action但却能多个category;
使用隐式Intent调用系统的浏览器来打开百度:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.baidu.com/"));
startActivity(intent);
使用隐式Intent调用系统内置的打电话的功能:
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
更多关于Intent详细的用法(例如:geo显示地理位置)请查看Intent API
当用户在一个活动中按了返回键通过重写下面的方法做相应的业务逻辑操作:
@Override
public void onBackPressed() {
super.onBackPressed();
Log.i(TAG, "onBackPressed:我按了返回键哦~");
}

三、Activity的生命周期

返回栈:一种后进先出(或者先进后出)的数据结构;Activity可以分为3种生存期:
(1)完整生存期:Activity在onCreate(完成各种初始化操作)方法和onDestroy(完成释放内存的操作)方法之间所经历的就是完整生命期。
(2)可见生存期:Activity在onStart(为了合理地管理那些对用户可见的资源,在onStart方法中对资源进行加载)方法和onStop(对资源进行释放)方法之间所经历的就是可见生存期.
(3)前台生存期:Activity在onResume()方法和onPause()方法之间所经历的就是前台生存期。
避免系统内存不足Activity被回收造成数据丢失:
onCreate()方法中
if (savedInstanceState!=null){
String tempData = savedInstanceState.getString("data_key");
Log.d(TAG, "onCreate: "+tempData);
}
重写onSaveInstanceState()方法
@Override
protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        String tempData = "just do it";
        outState.putString("data_key",tempData);
}

四、Activity启动模式

4种standard、singleTop、singleTask和singleInstance;使用方法在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式;
随时知晓当前是哪个Activity;让其他Activity继承下面的BaseActivity
public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("BaseActivity", getClass().getSimpleName());
    }
}
随时随地退出程序:
public class ActivityCollector {
    public static List<Activity> activities = new ArrayList<>();
    public static void addActivity(Activity activity){
        activities.add(activity);
    }
    public static void removeActivity(Activity activity){
        activities.remove(activity);
    }
    public static void finishAll(){
        for (Activity activity:activities) {
            if (!activity.isFinishing()){
                activity.finish();
            }
        }
    }
    
}
android.os.Process.killProcess(android.os.Process.myPid());//用于杀死当前程序的进程


第三章

一、常用控件的使用方法

TextView、Button、EditText、ImageView、ProgressBar(visible表示可见;invisible表示控件不可见,但是它仍然占据原来的位置和大小;gone表示控件不仅不可见,而且不再占用任何屏幕空间)进度条横向的属性
style="?android:attr/progressBarStyleHorizontal"
android:max="100";AlertDialog、ProgressDialog setCancelable(false)表示不能通过back键取消这个ProgressDialog;Android百分比布局的引入以及使用:
 compile 'com.android.support:percent:25.0.1'

二、创建自定义控件(抽取相同的头部标题控件)

Title:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/title_bg">

    <Button
        android:id="@+id/title_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/back_bg"
        android:text="Back"
        android:textColor="#fff" />

    <TextView
        android:id="@+id/title_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Title Text"
        android:textColor="#fff"
        android:textSize="24sp" />

    <Button
        android:id="@+id/title_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/edit_bg"
        android:text="Edit"
        android:textColor="#fff" />

</LinearLayout>

TitleLayout:
public class TitleLayout extends LinearLayout {

public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.title, this);
        Button titleBack = (Button) findViewById(R.id.title_back);
        Button titleEdit = (Button) findViewById(R.id.title_edit);
        titleBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
            ((Activity) getContext()).finish();
            }
        });
        titleEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "You clicked Edit button",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

}
MainActivity.class
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionbar = getSupportActionBar();
        if (actionbar != null) {
            actionbar.hide();
        }
    }
}
activity_main:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.uicustomviews.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

inflate(R.layout.fragment_body_temperature, container, false);

三、ListView

inflate(R.layout.fragment_body_temperature, container, false);第三个参数只让父布局中声明的layout属性生效,但不为这个View添加父布局,因为一旦View有了父布局之后,它就不能再添加到ListView了;ListView中convertView的复用,提高效率;

四、RecyclerView

LayoutManager(实现水平布局)、GridLayoutManager(实现网格布局)和StaggeredGridLayoutManager(实现瀑布流布局);RecyclerView(强大之处)可以轻松实现子项中任意控件或布局的点击事件(点9图的制作);

第四章

一、Fragment

Fragment强大之处,可以在程序运行时动态地添加到活动当中;动态添加Fragment碎片分5步:
RightFragment rightFragment = new RightFragment();//1、创建碎片实例
FragmentManager fragmentManager = getSupportFragmentManager();//2、获取碎片的管理者
FragmentTransaction transaction = fragmentManager.beginTransaction();//3、开启一个事务
transaction.replace(R.id.right_layout,rightFragment);//4、向容器中添加或替换碎片
transaction.commit();//5、提交事务
在Framgent碎片中模拟返回栈:
transaction.addToBackStack(null);Fragment的生命周期查看官方文档;
Fragment动态加载布局的技巧:res目录下新建layout-large布局;新建layout-sw600dp代表屏幕宽度大于600dp加载layout-sw600dp该目录下的文件,屏幕宽度小于600dp时加载原来res下对应的布局;Fragment碎片同时兼容手机和平板(在layout-sw600dp中加一个news_content_fragment的id,如果能够找到这个id,则加载平板双页模式,如果没有找到则加载手机单页模式);

第五章

一、广播机制(Broadcast Receiver)

跨进程的通信方式(Exported表示允许这个广播接收本程序以外的广播;Enabled属性表示是否启用这个广播接收器.);为了安全,可以发送本地广播(通过Local
BroadcastManager类实现,只有本程序才能接收到);

二、Git 初识版本控制工具

git config --global user.name “MrSun”
git congfig –global user.email “Mrsun@gmail.com”
创建代码仓库:git init
.git文件夹用来记录本地所有的Git操作(查看当前目录所有文件夹ls -al)
提交本地代码:
一次性把所有文件都添加好:git add .;
提交:git commit -m “First commit”
忽略文件:修改根目录下面的.gitignore和app模板下面的.gitignore文件;
查看文件修改情况:git status
查看更改的内容:git diff
撤销未提交的修改:git checkout  app/src/main/java/com/example/providertest/MainActivity.class;(该撤销方式只是用于那些还没有add命令的文件)
取消添加:git reset HEAD  app/src/main/java/com/example/providertest/MainActivity.class;
查看提交记录:git log
查看其中一条记录:git log id -1;
查看这条提交记录具体修改了什么内容:git log id -1–p;
分支
查看当前版本库中有哪些分支:git branch
创建分支:git branch  version1.0;
删除分支:git branch –D  version1.0
切换分支:git checkout  version1.0
合并:git merge version1.0
将本地修改的内容同步到远程版本库:git  push  origin(远程版本库的Git地址)  master(同步到的分支)
将远程版本库上的修改同步到本地:git fetch origin master
查看远程版本库上到底修改了哪些东西:git diff  origin/master
将origin/master分支上的修改合并到主分支上:
Git merge  origin/master;
Pull命令相当于将fetch和merge两个命令放在一起执行;
从远程版本库中获取最新的代码并且合并到本地:
git pull  origin  master


第六章

详解持久化技术(文件存储、SharedPreference、SQLite数据库存储、ContentProvider)

一、文件存储

核心技术就是Context类提供的openFileInput()和openFileOutput()方法;(不适合保存一些较为复杂的文本数据);
MODE_PRIVATE:默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容,而MODE_APPEND:则表示如果该文件已经存在,就往文件里面追加内容,不存在就创建新文件.

二、SharedPreferences存储(记住密码案例的实现)

3步
SharedPreferences.Editor editor = getSharedPreferences("ID", MODE_PRIVATE).edit();
//1、获取一个SharedPreferences.Editor对象;
editor.putString("patientName",patientName);
//2、对象中添加数据
editor.commit();//3、或editor.apply()将添加的数据提交

三、SQLites数据库存储(适合存储大量复杂的关系型数据)

CURD(Create,Retrieve,Update,Delete):insert select update delete;query
SQLiteOpenHelper
SQL语句创建book:create table Book(
id integer primary key autoincrement,
author text,price real,pages integer,name  text)
命令行界面查看数据库:

1、adb shell(进入到设备的控制台) ;

2、进入cd  /data/data/包名/databases/目录下;ls 命令查看该目录里的文件;

3、sqlite3 +数据库名打开数据库;

4、.table命令查看目前数据库中有哪些表;5、通过.schema命令来查看建表语句;

6、键入.exit或.quit退出数据库的编辑;
升级数据库:
sqLiteDatabase.execSQL("drop table if exists Book");//如果数据库中存在Book表 就将它drop(删除)掉
sqLiteDatabase.execSQL("drop taable if exists Category");//如果数据库中存在Catgory表 就将它drop掉
onCreate(sqLiteDatabase);
MyDataBaseHelper myDataBaseHelper = new MyDataBaseHelper(this, "BookStore.db", null, 2);//2版本,用于升级数据库
myDataBaseHelper.getWritableDatabase();
使用LitePal工具(优化SQLiteDatabase)操作SQLite数据库(LitePal增(save())删(deleteAll())改(updateAll())查(findAll())操作);关于更多find操作请见书P252页;
将数据更新成默认值的操作:setToDefault();
对象关系映射:将面向对象的语言和面向关系的数据库之间建立一种映射关系;

第七章

探究内容提供器(ContentProvider)

一、ContentProvider主要用于在不同的应用程序之间实现数据共享的功能;它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性(只共享部分需要共享的数据)。(Android运行时权限);android共有一百多种权限,其中9组,共24种危险权限(高于Android6.0的设备上需要在代码中动态添加运行时权限);

二、访问其他程序中的数据

要想访问内容提供者中共享的数据,一定要借助ContentResolver(Context.getContentResolver())类,ContentResolver中提供了一系列的方法用于对数据进行CURD操作, insert()添加数据, update()更新数据, delete()删除数据,query()查询数据;不同于SQLiteDatabase使用一个Uri参数代替表名参数,Url由两部分组成:authority和path;
例如:Uri   content://com.example.app.provider/table1
协议声明        authority           path
URI通配符:
*:表示匹配任意长度的任意字符;
#:表示匹配任意长度的数字;
创建内容提供器的步骤:1、新建一个类去继承ContentProvider(实现相应的方法);

2、借助UriMatcher类轻松实现匹配URI的功能;

3、实现getType()中的业务逻辑(用于获取Uri对象所对应的MIME类型);

第八章

运用手机多媒体

一、使用通知

PendingIntent,取消通知(setAutoCancel()和cancel()方法),播放一段音频setSound(Uri.fromFile(new File(path))),让手机震动(需要加权限):setVibrate(new long[]{}),控制手机LED灯闪烁setLights(Color.GREEN,1000,1000),构建出富文本的通知内容,setStyle()方法,如长文字、图片等,setPriority()设置通知的重要程度;

二、调用摄像头和相册

打开摄像头拍照功能和从相册中选择照片两个案例;

三、播放多媒体文件

播放音频:MediaPlayer(更多详细的用法请查看Android  api);
播放视频:VideoView(更多详细的用法请查看Android  api);

第九章

使用网络技术

一、WebView的用法:

WebView webView = new WebView(this);
webView.getSettings().setJavaScriptEnable(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("http://www.baidu.com);

二、使用HttpURLConnection(更多详细的用法请查看Android  api)

三、 使用OkHttp

OkHttp GET请求:    
new Thread(new Runnable() {
@Override
public void run() {
        String url = "http://10.10.10.152:6688/Service1.asmx/GetWorkStation";
        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody body = new FormBody.Builder().add("inXml", "<Request>         <LoginName>5007</LoginName><Password></Password></Request>").build();
        Request request = new Request.Builder().url(url).post(body).build();
        Call call = okHttpClient.newCall(request);
        try {
              Response response = call.execute();
              Log.i(TAG, response.body().string());
              } catch (IOException e) {
                        e.printStackTrace();
                        }
                    }
                }).start();

四、解析XML格式数据(Apache服务器的下载和使用)

Pull解析方式、SAX解析方式(还可以用XStream框架解析XML)

五、解析Json格式数据(JSONObject、GSON、Jackson、FastJSON等)

网络公用类的抽取和接口回调的使用;


第十章

探究服务(服务是Android中实现程序后台运行的解决方案,后台长期运行的任务,依附于创建服务时所在的应用程序进程)

一、Android多线程编程

解析Handler异步消息处理机制,以及AsyncTask的使用,它的原理也是基于异步消息处理机制(封装);关于AsyncTask的详细用法请查看Android api;

二、 服务的基本用法

Activity和Service之间通信,通过bindService(Intent,ServiceConnection,BIND_AUTO_CREATE(绑定后自己创建))

三、 服务的生命周期

四、服务的更多技巧

1、前台服务(Notification实现类似于通知)
2、、使用IntentService(创建一个异步的、会自动停止的服务)
3、下载的示例(ServiceBestPractice项目)

第十一章

基于位置的服务
得到某个应用程序的指纹:keytool  -list –v   -keystore <签名文件路径>

一、使用百度定位(1、申请API Key;2、下载SDK,放在自己的项目中,添加相应的配置) LBSTest项目
二、选择定位模式(网络和GPS等)

获取看的懂的位置信息option.setIsNeedAddress(true);

三、使用百度地图

(1)    让地图显示出来,添加百度的自定义(com.baidu.mapapi.map.MapView)控件
SDKInitializer.initialize(getApplicationContext());
(2)    移动到我的位置;
(3)    让“我”显示在地图上;(百度地图的更详细的用法和更新请参考官方文档); http://lbsyun.baidu.com/

第十二章

最佳的UI体验----Material  Design实战
Meterial  Design谷歌的设计师们基于传统优秀的设计原则,结合丰富的创意和科学技术所发明的一套全新的界面设计语言;

一、Toolbar(support.v7.widget.Toolbar)

二、滑动菜单(DrawerLayout,侧滑菜单中显示的内容为NavigationView(menu将group的checkableBehavior属性指定为single))

三、悬浮按钮和可交互提示(FloatingActionButton(悬浮按钮)、Snackbar(处理点击事件)、CoordinatorLayout(一个加强版的FrameLayout))

四、卡片是布局(CardView)

Glide加载图片
Glide.with(context).load(Url).into(view);
AppBarLayout(解决RecyclerView遮挡Toolbar的问题)

五、下拉刷新

SwipeRefreshLayout(实现下拉刷新的功能)

六、可折叠式标题栏CollapsingToolbarLayout

第十三章

Android高级技巧

一、全局获取Context的技巧(Application)
二、使用Intent传递对象
三、定制自己的日志工具

(源码地址https://github.com/guolindev/booksource)


1 0
原创粉丝点击