安卓app开发_安卓app开发100个实例 - CSDN
精华内容
参与话题
  • 开发自己的第一个安卓app

    万次阅读 多人点赞 2017-03-30 11:16:42
    开发自己的第一个安卓app开发安卓app的时候,首先我们需要配置一下电脑的开发环境。到jdk官网下载最新版本的jdk安装包。 Window64位下载地址:...

    开发自己的第一个安卓app

    在开发安卓app的时候,首先我们需要配置一下电脑的开发环境。到jdk官网下载最新版本的jdk安装包。

    Window64位下载地址:http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jdk-8u112-windows-x64.exe

    下载完成后,全部默认安装,一直点击下一步知道完成。在安装的过程中,会安装两个jdk和jre(java环境)。

    之后就是配置环境变量。

    配置环境变量参考下面的链接:

    http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html

    配置成功后,java的开发环境已经弄好了。下一步就是下载android开发的开发工具了。在这里,我建议使用android studio,因为google已经放弃了对eclipse的支持,目前在开发者也正在从eclipse中向android studio转移。

    下载android studio首先登陆android studio的官网:http://www.android-studio.org/index.php/download

    下载完成后,点击安装,全部默认,傻瓜式点击下一步直到完成。在其间会显示下载android sdk的提示框,并有下载的进度条,其实这里并不是从网络下载,因为我们下载的安装包中已经包含了sdk,所以这里的下载和进度其实是表示解压的进度。

     全部安装完成后,启动android studio的界面是这样的。

    这时候可以点击图片中的箭头选项,来创建一个安卓项目。

    点击下一步

    点击完成

    项目创建完成

    想对整个界面的各个部分深入了解的同学可以参考这篇文章

    链接:http://ms.csdn.net/geek/87819(可能手机才能正常显示)

    下面我们来点击运行

    会给出这样的提示

    说明我们还没有启动安卓虚拟机。现在比较流行的安卓虚拟机有genymotion

    官网为:http://www.genymotion.net/

    但我本人比较喜欢用夜神模拟器,链接为:http://www.yeshen.com/

    点击下载安装即可。全部是下一步直到完成。

    然后我们启动夜神模拟器

    可能一开始会以平板的形式显示,可以在设置中设置为手机

    然后点击保存,并重新启动。

    启动成功之后,在回到android studio,重新运行app

    选择设备。

    点击ok,android studio就开始构建和编译了。成功后会将app安装到安卓虚拟机上。

    安装成功后,手机屏幕已经显示了我们的第一个安卓app

    在桌面上已经多了一个Firstapp的应用了。

    这就是和大家分享的第一篇文章,实现自己的第一个安卓app

    展开全文
  • 安卓 Android开发简单小应用(一)

    万次阅读 多人点赞 2018-10-30 11:29:32
    安卓 Android开发简单小应用(一) 一、简述  记 --没学过Android开发简单小应用。(课程设计作业)  例子打包:链接:https://pan.baidu.com/s/1LEQ1oWkUX8OmtfCFVydxWQ 密码:9o0d 二、环境搭建 软件打包:...

    安卓 Android之开发简单小应用(一)

    一、简述

        记 --没学过Android之开发简单小应用。(课程设计作业)

        例子打包:链接:https://pan.baidu.com/s/1LEQ1oWkUX8OmtfCFVydxWQ 密码:9o0d

    二、环境搭建

    软件打包:链接:https://pan.baidu.com/s/1VVsZqPrwOtvMuzeeJE1y_A 密码:qspp

    下载解压即可

    1、安装JDK  (默认即可)

    2、设置环境变量

          2.1右键计算机--》属性--》高级系统设置--》高级--》环境变量

           2、2 新建变量名【ClassPath】,其值可设为 【.;%JAVA_HOME%/lib/rt.jar;%JAVA_HOME%/lib/tools.jar】。前面有个.

    (如果使用1.5以上版本的JDK,不用设置CLASSPATH环境变量,也可以正常编译和运行Java程序。)

           2、3找到Path变量,点击【编辑】,在变量值最前面加上【%JAVA_HOME%/bin;】后面有个分号“;”

    注意:记得点击确定

    补充:使用命令脚本设置环境变量,将一下内容保存为xxx.bat或xxx.cmd,然后双击运行(可能需要管理员权限)。

       (记得JAVA_PATH环境变量的值是JDK的实际安装路径,需要根据实际情况进行更改)

    ::先删除之前的JAVA_HOME(防止歧义)
    wmic ENVIRONMENT where "name='JAVA_HOME'" delete
    ::先删除之前的ClASSPATH 
    wmic ENVIRONMENT where "name='CLASSPATH'" delete
    ::创建名称为JAVA_HOME的系统环境变量, VariableValue :是JDK的安装路径
    wmic ENVIRONMENT create name="JAVA_HOME",username="<system>",VariableValue="C:\Program Files (x86)\Java\jdk1.7.0_45"
    ::备份Path环境变量(防止改错了)
    echo %Path%>Path.txt
    ::在系统环境变量Path中增加关于java的环境变量
    wmic ENVIRONMENT where "name='Path' and username='<system>'" set VariableValue=".;%%JAVA_HOME%%\bin;%%JAVA_HOME%%\jre\bin" 
    ::创建CLASSPATH系统环境变量 (听说这个可以不加)
    wmic ENVIRONMENT create name="CLASSPATH",username="<system>",VariableValue=".;%%JAVA_HOME%%\lib\dt.jar;%%JAVA_HOME%%\lib\tools.jar;" 
    ::暂停一下
    pause

    3、打开ADT (不用安装,解压后打开即用)     ADT:Android Developer Tools 安卓开发者工具

    三、新建一个工程

    然后一直点击"Next",直到点击"finish"完成。

    没有创建过虚拟设备的(模拟手机设备),需要新建。(有创建过的可以不用再创建,当然也可以进行修改虚拟设备的型号)

    四、运行项目

    右击项目--》Run As--》Andriod Application

    启动虚拟设备时信息输出

    成功启动之后,自动运行刚才运行的应用

    在项目文件下的bin 目录生成对应的.apk文件,可以直接安装到安卓手机

    五、总结

    1、启动虚拟设备之后,修改了代码,需要再次Run As程序,需要在虚拟设备中退出该应用,因为每Run As一次就会安装一次,先退出上一个版本的应用,再安装,否则可能安装失败。(不用退出虚拟设备,每一开启虚拟设备太耗时间)

    2、调试信息输出,比如说System.out.println("程序已经执行到这里了");默认是看不到的输出信息的,需要设置,(可能需要重启ADT方可生效)

    3、设置中文输入

    4、新建activity(新建一个页面)

    5、实现页面跳转并在第二个页面关闭时想第一个页面传递数据

        5.1在第一个页面添加一个按钮(直接拖拽到相应的布局文件即可)(就是打开)

    注:直接修改文本会有一个叹号,可以使用string.xml,这样就不会有叹号

     

       

     5.2写代码从第一个界面跳转到第二个界面

        5.3第一个界面对应的代码为MainActivity.java

      5.4跳转代码

    5.5当第二个页面关闭返回时的处理代码

    5.6编写第二个页面的代码(TwoActivity.java)

    5.7效果:

    6、设置app的名字

    7、导入已存在的项目

    8、设置字体

    展开全文
  • 基于Android Studio的简易天气APP项目开发

    万次阅读 多人点赞 2019-02-23 13:28:53
    一、功能需求 1、罗列全国的省、市、县 2、查看全国任意城市的天气情况 3、自由切换城市,查看异地城市的天气情况 4、手动更新与后台自动更新天气的功能 二、可行性分析: 1、需要用到的技术有:UI、网络、数据存储...

    参考文献:第一行代码(第二版),郭霖
    源码地址:https://github.com/2066972218/coolweather/commits/master

    一、功能需求
    1、罗列全国的省、市、县
    2、查看全国任意城市的天气情况
    3、自由切换城市,查看异地城市的天气情况
    4、手动更新与后台自动更新天气的功能

    二、可行性分析:
    1、需要用到的技术有:UI、网络、数据存储、服务
    2、天气信息来源:和风天气,有3000+次/天免费数据获取
    3、架设服务器用于提供全国的省市县的数据信息

    三、全国地区信息获取

    1、访问 http://guolin.tech/api/china 得到以下全国地区数据,其包括了中国所有的省份以及省份的id:在这里插入图片描述
    这是一个JSON格式的数组,在网址后加相应城市的id可以得到该省份城市下的所有市级城市,如:
    http://guolin.tech/api/china/30
    在这里插入图片描述在网址后继续键入id,可以得到该市级下的县级城市:
    如:http://guolin.tech/api/china/30/304
    在这里插入图片描述
    可以看到每一个县级城市都有一个weather_id,我们可以通过这个id去访问和风天气的接口,从而过去该地区的的天气情况。

    2、使用和风天气的接口
    注册账号:http://guolin.tech/api/weather/register
    选择免费用户,注册成功后,去邮箱激活,在这里插入图片描述之后登陆该账号,https://console.heweather.com/ 查看API接口说明文档。

    3、Git时间
    https://github.com/ 为GitHub官网,注册登陆,点击start a project~输入Coolweather~选择Android项目类型的gitignore文件和Apach License2.0作为天气的开源协议
    在这里插入图片描述
    创建成功后出现以下界面,其中README.md为版本库主页说明,点击Clone or download按钮,将该复制到剪贴板:在这里插入图片描述
    版本库主页为:https://github.com/2066972218/coolweather

    在Android Studio中新建一个项目CoolWeather,然后将远程代码库克隆值本地,在Termiminal中输入
    git clone https://github.com/2066972218/coolweather.git,
    如图所示,说明克隆成功。
    在这里插入图片描述
    在Android Studio中把项目文件下的CoolWeather/coolweather的所有文件,包括隐藏的.git文件剪切(mv .git .. /)到CoolWeather文件目录下。

    接下来通过在Termiminal中输入一下代码,将CoolWeather项目中的文件上传到Git版本控制中。
    git add .
    git commit -m "First commit"
    git push origin master
    在执行最后一条语句时发生一个错误,借助博客链接:
    https://blog.csdn.net/jingfengvae/article/details/72859130 解决。
    提交成功后,看版本库已经更新成功,也就是我们的代码已经提交值远程代码库了,如图:
    在这里插入图片描述
    也就是我们该项目的版本控制Git创建好了,下面我们来继续项目编码。

    4、数据库的创建与配置
    创建4个包db、gson、service、util,db包用于存放数据库模型的代码、gson用于存放GSON模型的相关代码,util包用于存储工具相关代码。在这里插入图片描述
    为简化数据库的操作我们采用LitePal来管理项目的数据库,先添加好一下我们后续需要用到的依赖闭包:

        //用于对数据库进行操作
        implementation 'org.litepal.android:core:1.4.1'
        //用于进行网络请求
        implementation 'com.squareup.okhttp3:okhttp:3.4.1'
        //用于JSON解析
        implementation 'com.google.code.gson:gson:2.7'
        //用于加载和展示图片
        implementation 'com.github.bumptech.glide:glide:3.7.0'
    

    在db包下我们创建三张表(实体类):province、city、county分别存放省市县的数据信息。
    province实体类如下:

    public class Province extends DataSupport {
       private int id;//每个实体类都有的字段
       private String provinceName;//记录省份名字
       private int provinceCode;//记录省的代号
       public int getId() {
           return id;
       }
       public void setId(int id) {
           this.id = id;
       }
       public String getProvinceName() {
           return provinceName;
       }
       public void setProvinceName(String provinceName) {
           this.provinceName = provinceName;
       }
       public int getProvinceCode() {
           return provinceCode;
       }
       public void setProvinceCode(int provinceCode) {
           this.provinceCode = provinceCode;
       }
    }
    

    同理,新建的City类,代码如下:

    public class City extends DataSupport {
        private int id;   //每一个实体类都有一个id
        private String cityName;  //记录市名称
        private int cityCode;   //几率市的代码
        private int provinceCode;  //记录该市的上级省级代码
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getCityName() {
            return cityName;
        }
        public void setCityName(String cityName) {
            this.cityName = cityName;
        }
        public int getCityCode() {
            return cityCode;
        }
        public void setCityCode(int cityCode) {
            this.cityCode = cityCode;
        }
        public int getProvinceCode() {
            return provinceCode;
        }
        public void setProvinceCode(int provinceCode) {
            this.provinceCode = provinceCode;
        }
    }
    

    同理,记录代表区县的County类,如下:

    public class County extends DataSupport {
        private int id;//每一个实体类都需有一个id
        private String countyName; //记录区县名称
        private int countyCode;//记录区县代码
        private int weatherId;//记录该区县的天气信息
        private int cityId;//该区县所属的市级代码
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getCountyName() {
            return countyName;
        }
        public void setCountyName(String countyName) {
            this.countyName = countyName;
        }
        public int getCountyCode() {
            return countyCode;
        }
        public void setCountyCode(int countyCode) {
            this.countyCode = countyCode;
        }
        public int getWeatherId() {
            return weatherId;
        }
        public void setWeatherId(int weatherId) {
            this.weatherId = weatherId;
        }
        public int getCityId() {
            return cityId;
        }
        public void setCityId(int cityId) {
            this.cityId = cityId;
        }
    }
    

    以上我们也就完成这三个实体类的内容,接下配置数据库

    在main目录下创建一个assets的的路径,在该路径下创建一个litepal.xml文件,在该文件输入:

    <?xml version="1.0" encoding="utf-8"?>
    <litepal>
        <dbname value = "cool_weather"/>    //指定数据库名
        <version value = "1"/>     //数据库版本号
        <!--将三个实体类添加到映射列表中-->
        <list>
            <mapping class = "com.example.coolweather.db.Province"/>
            <mapping class = "com.example.coolweather.db.City"/>
            <mapping class = "com.example.coolweather.db.County"/>
        </list>
    </litepal>
    

    最后修改AndroidManifest.xml中添加以下代码:

     <application
        android:usesCleartextTraffic="true"
        android:name="org.litepal.LitePalApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        </application>
    

    现在数据库配置完毕了,数据库和表会在首次执行自行创建,现在我们将这一阶段的代码提交到版本控制中,即在Terrminal中输入如下:
    git add .
    git commit -m "加入创建数据库和表的各项配置"
    git push origin master

    5、加载全国省市县的所有数据
    从上面我们知道全国的省市县信息我们都是从服务器中获取的,所有这里我们需要与服务其进行交互。在util中创建一个HttpUtil类。

    public class HttpUtil {
        public static void sendOKHttpRequest(String adress, okhttp3.Callback callback){
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(adress).build();
            client.newCall(request).enqueue(callback);
        }
    }
    

    根据三的全国地区信息知道我们获取的信息为JSON格式的,需要解析后才能存入数据库,在util文件中新建一个Utility工具类来解析和处理这些信息。如下:

    public class Utility {
        /*解析和处理服务器返回的省级数据 */
        public static boolean handleProvinceResponse(String response){
            if (!TextUtils.isEmpty(response)){  //如果返回的数据不为空
                try {
                    //将所有的省级数据解析出来,并组装成实体类对像
                    JSONArray allProvinces = new JSONArray(response);
                    for (int i=0;i<allProvinces.length();i++){
                        JSONObject provinceObject = allProvinces.getJSONObject(i);
                        Province province = new Province();
                        province.setProvinceName(provinceObject.getString("name"));
                        province.setProvinceCode(provinceObject.getInt("id"));
                        //将该实体类对象存入数据库
                        province.save();
                    }
                    return true;//解析成功
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return false;//解析失败
        }
    
        /*解析和处理服务器返回的市级数据 */
        public static boolean handleCityResponse(String response,int provinceId){
            if (!TextUtils.isEmpty(response)){
                try {
                    JSONArray allCities = new JSONArray(response);
                    for (int i=0;i<allCities.length();i++){
                        JSONObject cityObject = allCities.getJSONObject(i);
                        City city = new City();
                        city.setCityCode(cityObject.getInt("id"));
                        city.setCityName(cityObject.getString("name"));
                        city.setProvinceCode(provinceId);  //所属的省级代号
                        city.save();
                    }
                    return true;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
        /*解析和处理服务器返回的县级数据 */
        public static boolean handleCountyResponse(String response,int cityId){
            if (!TextUtils.isEmpty(response)){
                try {
                    JSONArray allCounties = new JSONArray(response);
                    for (int i=0;i<allCounties.length();i++){
                        JSONObject countyObject = allCounties.getJSONObject(i);
                        County county = new County();
                        county.setCountyName(countyObject.getString("name"));
                        //县级天气信息
                    county.setWeatherId(countyObject.getString("weather_id"));
                        //所属的市级代号
                        county.setCityId(cityId);
                        county.save();
                    }
                    return true;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
    }
    

    解析出省市县的数据后,现在我们来编写界面UI,为后面我们布局复用,因为我们不实用原生的ActionBar
    er,故我们在style.xml将其设置为

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    

    我们将界面写在碎片里,新建布局文件choose_area.xml,如下:

    <?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"
        android:orientation="vertical"
        android:background="#fff">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimary">
    
            <TextView
                android:id="@+id/title_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:textColor="#fff"
                android:textSize="20sp"/>
            <Button
                android:id="@+id/back_button"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="10dp"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:background="@drawable/ic_back" />        
        </RelativeLayout>
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    

    创建一个AreaFragment继承自Fragment,在其中编写遍历全国的省市县数据,通过从数据库获取和网络获取两种方式来加载全国省市县数据,逻辑代码如下:

    public class ChooseAreaFragment extends Fragment {
    
        public static final int LEVEL_PROVINCE=0;
        public static final int LEVEL_CITY=1;
        public static final int LEVEL_COUNTY=2;
    
        private ProgressDialog progressDialog;
    
        private TextView titleText;
    
        private Button backButton;
    
        private ListView listView;
    
        private ArrayAdapter<String> adapter;
    
        private List<String> dataList = new ArrayList<>();
    
        private int currentLevel;  //当前被选中的级别
        private Province selectedProvince;//被选中的省份
        private City selectedCity;//被选中的城市
    
        private List<Province> provinceList;//省列表
        private List<City> cityList;//市列表
        private List<County> countyList ;//县列表
    
        /*获取控件实例id*/
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            Log.d("ChooseAreaFragment","onCreateView");
            View view = inflater.inflate(R.layout.choose_area,container,false);
            titleText = (TextView)view.findViewById(R.id.title_text);  //获取标题栏文本id
            backButton = (Button) view.findViewById(R.id.back_button);  //获取标题栏id
            listView = (ListView)view.findViewById(R.id.list_view);    //获取Item列表id
            //获取ArrayAdapter对象
            adapter =new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, dataList);
            listView.setAdapter(adapter);//设置并初始化适配器
            return view;//将视图返回
        }
     
        /*点击事件集合*/
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            Log.d("ChooseAreaFragment","onActivityCreated");
            super.onActivityCreated(savedInstanceState);
            //列表任意一栏被点击,则...
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Log.d("ChooseAreaFragment","列表被点了的...");
                    if (currentLevel == LEVEL_PROVINCE){   //当前选中的级别为省份时
                        selectedProvince = provinceList.get(position);  //当前点击为选中状态
                        queryCities();//查询市的方法
                    }
                    else if (currentLevel == LEVEL_CITY){
                        selectedCity = cityList.get(position);
                        queryCounties();
                    }
                }
            });
            backButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (currentLevel == LEVEL_COUNTY){
                        queryCities();
                    }
                    else if (currentLevel == LEVEL_CITY){
                        queryProvinces();
                    }
                }
            });
            queryProvinces();
        }
    
        private void queryCities() {
            titleText.setText(selectedProvince.getProvinceName());  //设置市的标题内容
            backButton.setVisibility(View.VISIBLE);  //设置返回按钮可见
            //查询被选中的省份城市的市区
            cityList = DataSupport.where("provinceid=?",String.valueOf(selectedProvince.
                            getId())).find(City.class);
            Log.d("ChooseAreaFragment","市级");
            if (cityList.size()>0){ //如果省列表不为空,则...
                dataList.clear();
                for (City city:cityList){ //遍历每一份省的市级城市
                    dataList.add(city.getCityName()); //添加到数据列表中
                }
                adapter.notifyDataSetChanged();//通知适配器数据更新了
                listView.setSelection(0);
                currentLevel = LEVEL_CITY;
            }
            else{
                int provinceCode = selectedProvince.getProvinceCode();  //获取被选取省级代码
                String address = "http://guolin.tech/api/china/"+provinceCode;//获取被选取地区的网络地址
                Log.d("ChooseAreaFragment","准备在网络中获取地址信息");
                queryFromServer(address,"city");   // 在网络中查询
            }
        }
        /*根据传入的地址和类型从服务器查询省市县数据*/
        private void queryFromServer(String adress, final String type) {
            showProgressDialog();
            //   发送一条网络请求
            HttpUtil.sendOKHttpRequest(adress, new Callback() {
    
                //请求加载失败
                @Override
                public void onFailure(Call call, IOException e) {
                    //通过runOnUiThread方法回到主线程逻辑
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            closeProgressDialog();
                            Toast.makeText(getContext(),"加载失败",Toast.LENGTH_SHORT).show();
                        }
                    });
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Log.d("ChooseAreaFragment","加载地区信息...");
                    String responseText = response.body().string();
                    boolean result = false;
                    if ("province".equals(type)){
                        result = Utility.handleProvinceResponse(responseText);
                    }
                    else if ("city".equals(type)){
                        result = Utility.handleCityResponse(responseText,selectedProvince.getId());
                    }
                    else if ("county".equals(type)){
                        result = Utility.handleCountyResponse(responseText, selectedCity.getId());
                    }
                    if (result)
                    {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d("ChooseAreaFragment","开启线程更新UI");
                                closeProgressDialog();
                                if ("province".equals(type)){
                                    queryProvinces();
                                }
                                else if ("city".equals(type)){
                                    queryCities();
                                }
                                else if ("county".equals(type)){
                                    queryCounties();
                                }
                            }
                        });
                    }
    
                    if ("city".equals(type)){
                        result = Utility.handleProvinceResponse(responseText);
                    }
                    if ("county".equals(type)){
                        result = Utility.handleProvinceResponse(responseText);
                    }
    
    
                }
            });
        }
    
        /*显示进度对话框*/
        private void showProgressDialog() {
            if (progressDialog==null){
                progressDialog = new ProgressDialog(getActivity());
                progressDialog.setMessage("正在加载...");
                progressDialog.setCanceledOnTouchOutside(false);
    
            }
            progressDialog.show();
        }
    
        private void queryCounties() {
            titleText.setText(selectedCity.getCityName());
            backButton.setVisibility(View.VISIBLE);
            countyList = DataSupport.where("cityid = ?", String.valueOf(selectedCity.getId())).find(County.class);
            if (countyList.size()>0){
                dataList.clear();
                for (County county:countyList){
                    dataList.add(county.getCountyName());
                }
                adapter.notifyDataSetChanged();
                listView.setSelection(0);
                currentLevel=LEVEL_COUNTY;
            }
            else {
                int provinceCode = selectedProvince.getProvinceCode();
                int cityCode = selectedCity.getCityCode();
                String address = "http://guolin.tech/api/china/"+provinceCode+"/"+cityCode;
                queryFromServer(address,"county");
            }
        }
    
        /*全国所有的省,优先查询数据库,如果没有再去服务器查询*/
        private void queryProvinces() {
            titleText.setText("中国");
            Log.d("ChooseAreaFragment","查询省中...");
            backButton.setVisibility(View.GONE);
            provinceList = DataSupport.findAll(Province.class);
            if (provinceList.size()>0){
                dataList.clear();
                for (Province province:provinceList){
                    dataList.add(province.getProvinceName());
                }
                adapter.notifyDataSetChanged();
                listView.setSelection(0);
                currentLevel = LEVEL_PROVINCE;
            }
            else {
                Log.d("ChooseAreaFragment","服务器查询省中...");
                String address = "http://guolin.tech/api/china";
                queryFromServer(address,"province");
            }
        }
        private void closeProgressDialog() {
            if (progressDialog!=null){
                progressDialog.dismiss();
            }
        }
    }
    

    接下来将碎片县市县碎片县市在主布局中,修改activity.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <fragment
            android:id="@+id/choose_area_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name = "com.example.coolweather.ChooseAreaFragment" />
    </FrameLayout>
    

    添加网络访问权限:

    <uses-permission android:name="android.permission.INTERNET"/>
    

    别忘了添加:

    android:usesCleartextTraffic="true"
    

    运行过程中出现一个错误为:

    no such column: provinceId (code 1): , while compiling: SELECT * FROM city WHERE provinceId

    说是在city中没有找到provinceId者一列的数据库,经分析为数据库在没有创建city列表前有创建国数据库,所有这里我们将litepal.xml中的版本号升级为2,即:

     <version value = "2"/>     //数据库版本号
    

    查看下运行图:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    第一部分也就完成了,将代码提交到远程仓库:

    CoolWeather apple$ git add .
    
    CoolWeather apple$ git commit -m "遍历中国省市县三级列表显示功能"
    
    CoolWeather apple$ git push origin master
    

    6、显示天气信息
    由于获取的天气信息较为复杂,我们采用GSON来获取天气信息。
    在gson包中建立一个Basic类,来显示城市的基础信息:

    public class Basic {
        @SerializedName("city")   //JSON字段和Java字段建立映射
        public String cityName;   //城市名
        @SerializedName("id")
        public String weather_id;  //天气情况
        public Update update;  
        public class Update {
            @SerializedName("loc")
            public String updateTime;   //天气更新时间
        }
    }
    

    同理,新建一个AQI类:

    public class AQI {
        public AQICity city;
        public class AQICity{
            public String aqi;
            public String pm25;
        }
    }
    

    新建一个Now类显示温度和天气情况:

    public class Now {
        @SerializedName("tmp")
        public String tempeture;
        @SerializedName("cond")
        public More more;
        private class More {
            @SerializedName("txt")
            public String info;
        }
    }
    

    新建一个Suggestion类来推荐日常活动:

    public class Suggestion {
        @SerializedName("comf")
        public Comfort comfort;   
        @SerializedName("cw")
        public  CarWash carWash;    
        public Sport sport;
        public class Comfort {
            @SerializedName("txt")
            public String info;
        }
        public class CarWash{
            @SerializedName("txt")
            public String info;
        }
        private class Sport {
            @SerializedName("txt")
            public String info;
        }
    }
    

    继续在gson包下新建一个Forecas的类开表示未来的天气情况,其包含的会是一个数组:

    public class Forecast {
        public String data;
        @SerializedName("tmp")
        public Temperature temperature;
        @SerializedName("cond")
        public More more;
        public class Temperature {
            public  String max;
            public String min;
        }
        private class More {
            @SerializedName("txt_d")
            public String info;
        }
    }
    

    新建一个总的实例类,在gson下的Weather类来引用刚创建的各个实体类:

    public class Weather {
       public String status;  //返回是否成功返回值
       public Basic basic;
       public Forecast forecast;
       public AQI aqi;
       public Now now;
       @SerializedName("daily_forecast")
       public List<Forecast> forecastList;  //解析出数组
    

    GSon所有的实体类都定义好后,下面来编写天气界面UI
    创建一个活动为WeatherActivity,布局指定为activity_weather.xml,这个界面我们用分模块来构建布局UI,后面在使用include来集成:
    首先建立一个title.xml作为头布局,在该头布局中放置两个TextView用于分别显示:城市名和显示更新事件,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="?attr/actionBarSize">
       <TextView
           android:id="@+id/title_city"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_centerInParent="true"
           android:textColor="#fff"
           android:textSize="20sp"/>
       <TextView
           android:id="@+id/title_update_time"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_marginRight="10dp"
           android:layout_alignParentRight="true"
           android:layout_centerVertical="true"
           android:textColor="#fff"
           android:textSize="16sp"/>
    </RelativeLayout>
    

    在新建一个now.xml来显示天气信息,包括当前气温和天气概况,如下:

    <LinearLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
       <!--显示当前气温-->
       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" 
           android:id="@+id/degree_text"
           android:layout_gravity="end"
           android:textSize="60sp"
           android:textColor="#fff"
           />
       <!--显示天气概况-->
       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" 
           android:id="@+id/weather_info_text"
           android:layout_gravity="end"
           android:textSize="20sp"
           android:textColor="#fff"/>
    </LinearLayout>
    

    在新建forecast.xml来显示未来几天的天气:

    <?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:orientation="vertical"
        android:layout_margin="15dp"
        android:background="#8000">
        <!--定义了一个标题-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginTop="15dp"
            android:text="预报"
            android:textColor="#fff"
            android:textSize="20sp"/>
        <!--未来几天天气信息的布局,需要根据服务器返回的数据在代码中动态添加-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:id="@+id/forecast_layout">
        </LinearLayout>
    </LinearLayout>
    

    在定义一个未来天气的子项布局forecast_item.xml,如下:

    <?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:layout_margin="15dp">
        <!--天气时间-->
        <TextView
            android:id="@+id/data_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="2"
            android:textColor="#fff"/>
        <!--天气概况-->
        <TextView
            android:id="@+id/info_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content" 
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:gravity="center"
            android:textColor="#fff"/>
        <!--最高温度-->
        <TextView
            android:id="@+id/max_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content" 
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="right"
            android:textColor="#fff"/>
        <!--最低气温-->
        <TextView
            android:id="@+id/min_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="right"
            android:textColor="#fff"/>   
    </LinearLayout>
    

    新建一个aqi.xml作为空气质量的布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:background="#8000">    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginTop="15dp"
            android:text="空气质量"
            android:textColor="#fff"
            android:textSize="20sp"/>    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp">
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1">            
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_centerInParent="true">
                    
                    <TextView
                        android:id="@+id/aqi_text"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textColor="#fff"
                        android:textSize="40sp"/>
                    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" 
                        android:layout_gravity="center"
                        android:text="AQI指数"
                        android:textColor="#fff"/>
                </LinearLayout>
            </RelativeLayout>
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_centerInParent="true">
    
                    <TextView
                        android:id="@+id/pm25_text"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textColor="#fff"
                        android:textSize="40sp"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="PM2.5指数"
                        android:textColor="#fff"/>
                </LinearLayout>
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>
    

    在新建一个suggestion.xml来作为生活建立信息布局,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:background="#8000">    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:layout_marginLeft="15dp"
            android:layout_marginTop="15dp"
            android:text="生活建议"
            android:textColor="#fff"
            android:textSize="20sp" />
        <!--舒适度-->
        <TextView
            android:id="@+id/comfort_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:textColor="#fff"/>
        <!--洗车指数-->
        <TextView
            android:id="@+id/car_wash_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:textColor="#fff"/>
        <!--运动建议-->
        <TextView
            android:id="@+id/sport_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:textColor="#fff"/>
    </LinearLayout>
    

    最后将以上编写的布局引入到activity_weather.xml中,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary">    
        <ScrollView
            android:id="@+id/weather_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            android:overScrollMode="never">        
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">            
                <include layout="@layout/title"/>            
                <include layout="@layout/now"/>         
                <include layout="@layout/forecast"/>
                <include layout="@layout/api"/>
                <include layout="@layout/suggestion"/>
            </LinearLayout>
        </ScrollView>
    </FrameLayout>
    

    以上天气UI我们就编写完毕了,看一下效果:
    在这里插入图片描述
    接下来,开始逻辑部分的实现,首先得在Utility类中添加解析天气JSON数据的方法:

     /*将返回的JSON数据解析成Weather实体类*/
        public static Weather handleWeatherResponse(String response){
            try {
                //通过JSONObject和JSONArray将天气数据中的主体内容解析出来
                JSONObject jsonObject = new JSONObject(response);   
                JSONArray jsonArray = jsonObject.getJSONArray("HeWeather");
                String weatherContent = jsonArray.getJSONObject(0).toString();
                //将JSON数据转换成Weather对象
                return new Gson().fromJson(weatherContent,Weather.class);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }
    

    接着,在WeatherActivity中去请求天气数据,以及将数据展示到界面上,记得key值需要自己去和风天气官网去获取,每个人每个应用的的key不一样:

    public class WeatherActivity extends AppCompatActivity {                                                           
                                                                                                                      
       private ScrollView weatherLayout;                                                                              
                                                                                                                      
       private TextView titleCity;                                                                                    
                                                                                                                      
       private TextView titleUpdateTime;                                                                              
                                                                                                                      
       private TextView degreeText;  //气温                                                                             
                                                                                                                      
       private TextView weatherInfoText;  //天气概况                                                                      
                                                                                                                      
       private LinearLayout forecastLayout;                                                                           
                                                                                                                      
       private TextView aqiText;                                                                                      
                                                                                                                      
       private TextView pm25Text;                                                                                     
                                                                                                                      
       private TextView comfortText;                                                                                  
                                                                                                                      
       private TextView carWashText;                                                                                  
                                                                                                                      
       private TextView sportText;                                                                                    
                                                                                                                      
       @Override                                                                                                      
       protected void onCreate(Bundle savedInstanceState) {                                                           
           super.onCreate(savedInstanceState);                                                                        
           setContentView(R.layout.activity_weather);                                                                 
           initView();                                                                                                
           //定义缓存对象                                                                                                   
           SharedPreferences prefs= PreferenceManager.getDefaultSharedPreferences(this);                              
           String weatherString = prefs.getString("weather",null);                                                    
           if (weatherString!=null){                                                                                  
               //有缓存时直接解析天气数据                                                                                         
               Weather weather = Utility.handleWeatherResponse(weatherString);                                        
               showWeatherInfo(weather);                                                                              
           }                                                                                                          
           else {                                                                                                     
               //无缓存时去服务器查询天气信息                                                                                       
               String weatherId = getIntent().getStringExtra("weather_id");                                           
               weatherLayout.setVisibility(View.INVISIBLE);                                                           
               requestWeather(weatherId);                                                                             
           }                                                                                                          
       }                                                                                                              
        /*根据天气ID请求天气信息*/                                                                                              
       private void requestWeather(final String weatherId) {                                                          
           String weatherUrl = "http://guolin.tech/api/weather?cityid = "+                                            
                   weatherId+"&key = 8614c6b9de8145b3a0ef78a277cc2db4";                                               
           HttpUtil.sendOKHttpRequest(weatherUrl, new Callback() {                                                    
               @Override                                                                                              
               public void onFailure(Call call, IOException e) {                                                      
                   e.printStackTrace();                                                                               
                   runOnUiThread(new Runnable() {                                                                     
                       @Override                                                                                      
                       public void run() {                                                                            
                           Toast.makeText(WeatherActivity.this,"从网上获取天气信息失败",                                         
                                   Toast.LENGTH_SHORT).show();                                                        
                       }                                                                                              
                   });                                                                                                
               }                                                                                                      
               @Override                                                                                              
               public void onResponse(Call call, Response response) throws IOException {                              
                   final String responseText = response.body().string();                                              
                   final Weather weather = Utility.handleWeatherResponse(responseText);                               
                   runOnUiThread(new Runnable() {                                                                     
                       @Override                                                                                      
                       public void run() {                                                                            
                           if (weather!=null&&"ok".equals(weather.status)) {                                          
                               SharedPreferences.Editor editor = PreferenceManager.                                   
                                       getDefaultSharedPreferences(WeatherActivity.this).edit();                      
                               editor.putString("weather",responseText);                                              
                               editor.apply();                                                                        
                               showWeatherInfo(weather);                                                              
                           }                                                                                          
                           else {                                                                                     
                               Toast.makeText(WeatherActivity.this,"获取天气信息失败",                                        
                                       Toast.LENGTH_SHORT).show();                                                    
                           }                                                                                          
                       }                                                                                              
                   });                                                                                                
               }                                                                                                      
           });                                                                                                        
       }                                                                                                              
                                                                                                                      
       //缓存数据下处理并展示Weather实体类中的数据                                                                                     
       private void showWeatherInfo(Weather weather) {                                                                
           String cityName = weather.basic.cityName;                                                                  
           String updateTime = weather.basic.update.updateTime.split(" ")[1]; //split:分解                              
           String degree = weather.now.tempeture+"°C";                                                                
           String weatherInfo = weather.now.more.info;                                                                
           titleCity.setText(cityName);                                                                               
           titleUpdateTime.setText(updateTime);                                                                       
           degreeText.setText(degree);                                                                                
           weatherInfoText.setText(weatherInfo);                                                                      
           forecastLayout.removeAllViews();                                                                           
           for (Forecast forecast : weather.forecastList){                                                            
               View view = LayoutInflater.from(this).inflate(R.layout.forecast_item,forecastLayout,false);            
               TextView dateText = (TextView)view.findViewById(R.id.date_text);                                       
               TextView infoText = (TextView)view.findViewById(R.id.info_text);                                       
               TextView maxText = (TextView)view.findViewById(R.id.max_text);                                         
               TextView minText = (TextView)view.findViewById(R.id.min_text);                                         
               dateText.setText(forecast.date);                                                                       
               infoText.setText(forecast.more.info);                                                                  
               maxText.setText(forecast.temperature.max);                                                             
               minText.setText(forecast.temperature.min);                                                             
               forecastLayout.addView(view);                                                                          
           }                                                                                                          
           if (weather.aqi != null){                                                                                  
                    aqiText.setText(weather.aqi.city.aqi);                                                            
                    pm25Text.setText(weather.aqi.city.pm25);                                                          
           }                                                                                                          
           String comfort = "舒适度:" +weather.suggestion.comfort.info;                                                  
           String carWash = " 洗车指数:" +weather.suggestion.carWash.info;                                                
           String sport = "运动建议:" +weather.suggestion.sport.info;                                                     
           comfortText.setText(comfort);                                                                              
           carWashText.setText(carWash);                                                                              
           sportText.setText(sport);                                                                                  
           weatherLayout.setVisibility(View.VISIBLE);                                                                 
       }                                                                                                              
                                                                                                                      
       //初识化控件                                                                                                        
       private void initView() {                                                                                      
           weatherLayout = (ScrollView) findViewById(R.id.weather_layout);                                            
           titleCity = (TextView)findViewById(R.id.title_city);                                                       
           titleUpdateTime = (TextView)findViewById(R.id.title_update_time);                                          
           degreeText = (TextView)findViewById(R.id.degree_text);                                                     
           weatherInfoText = (TextView)findViewById(R.id.weather_info_text);                                          
           forecastLayout = (LinearLayout)findViewById(R.id.forecast_layout);                                         
           aqiText = (TextView)findViewById(R.id.api_text);                                                           
           pm25Text = (TextView)findViewById(R.id.pm25_text);                                                         
           comfortText = (TextView) findViewById(R.id.comfort_text);                                                  
           carWashText = (TextView) findViewById(R.id.car_wash_text);                                                 
           sportText = (TextView)findViewById(R.id.sport_text);                                                       
       }                                                                                                              
    }   
    

    实现省市县列表界面跳转到天气界面的逻辑:
    ,修改ChooseAreaFragment,如下:

       //列表任意一栏被点击,则...
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Log.d("ChooseAreaFragment","列表被点了的...");
                    if (currentLevel == LEVEL_PROVINCE){   //当前选中的级别为省份时
                        selectedProvince = provinceList.get(position);  //当前点击为选中状态
                        queryCities();//查询市的方法
                    }
                    else if (currentLevel == LEVEL_CITY){
                        selectedCity = cityList.get(position);
                        queryCounties();
                    }
    
                    /*以下实现地区天气界面*/
                    else if (currentLevel == LEVEL_COUNTY){
                        String weatherId = countyList.get(position).getWeatherId();
                        Intent intent = new Intent(getActivity(),WeatherActivity.class);
                        intent.putExtra("weather_id",weatherId);
                        startActivity(intent);
                        getActivity().finish();
                    }
                }
            });
    

    在MainActivity中加入一个缓存数据的判断如下:
    public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            if (prefs.getString("weather",null)!=null){
                Intent intent = new Intent(this,WeatherActivity.class);
                startActivity(intent);
                finish();
            }
        }
    }
    

    运行程序后发现和风天气的API接口以及更新升级了,也就是以上代码运行会存在Bug,如图:

    所以去看一下和风天气的开发文档:
    https://www.heweather.com/documents/sdk/android
    在来开发。

    展开全文
  • 前言 经过了两年多终于完成了这本书,2016年9月份开始写的,到今天为止2年零2个月,本书的内容大部分是去年完成的,看过我去年总结的读者可能知道,去年事情很多太忙了,导致本命年这本书没有上架(有点小小的遗憾)...

    前言

    经过了两年多终于完成了这本书,2016年9月份开始写的,到今天为止2年零2个月,本书的内容大部分是去年完成的,看过我去年总结的读者可能知道,去年事情很多太忙了,导致本命年这本书没有上架(有点小小的遗憾)。

    工作之余喜欢写写技术文章,对自己的技术做一个总结同时也让后来者站在我的肩膀上,之前一直在CSDN发表文章,也是CSDN博客专家,单篇文章上万阅读量,在这里感谢这个平台,让我的文章被更多人看到。

    为什么要写这本书?

    现在Android方面的书也蛮多的,但是都是讲基础的书籍或者技术都过时了,本书会结合我多年Android开发经验,讲解企业最常用的Android基础,并且学习最前沿的技术,让有Java SE基础的人能快速上手开发项目。

    章节内容介绍

    本书一共10个章节,从基础入门到高级初步。

    第1章学习了开发工具Android Studio,孔子云:“工欲善其事,必先利其器”,一个好的开发工具可以让开发人员的工作效率有大幅度的提高。

    第2章节讲解了Android控件相关知识,一个UI界面是由多个控件组成,只有熟练使用各种控件才能做出好看的App,达到UI设计师想要的效果。

    第3章节学习了Android中四大组件,在真实的企业开发中,四大组件的其中三个:Activity(活动)、Service(服务)、Broadcast Receiver(广播接收器)使用及其频繁,ContentProvider(内容提供者)使用频率相对少一些,只有某些需求需要用到时才会使用。

    第4章节学习了Fragment(碎片),从Fragment简单使用,到最后的案例开发,一步步深入的学习Fragment,使用了Fragment让我们的App模块化,还能解决手机跟平板适配问题。

    第5章学习了多线程开发,从多线程的创建,到字线程如何更新UI,通过阅读源码分析了Handle的实现原理,最后介绍了线程池的使用。

    第6章首先学习了Android网络编程,通过Get/Post方式向服务器发送Http请求,现在市面上大部分App跟服务器交互都是返回Json数据,所以介绍了Gson框架,还学习了OkHttp开源项目的使用以及封装,让我们站在巨人的肩膀上。最后还学习了数据存储的三种方式。

    第7章节学习了Android高级初步知识点,内容比较多、比较杂。主要介绍了Notification使用、多媒体开发、WebView使用、定位的三种方式、NDK跟JNI开发、Git管理项目等。

    第8章节学习介绍了Android中各大版本的更新,让我们的App解决版本适配问题,完美兼容5.0以上各个版本。站在技术的最前言,不输在起跑线上。

    第9章节学习了常用功能模板,这些功能是大家在企业开发中可能会碰到的需求,通过模版的学习,让我们知道对一个App中功能的划分,以及如何封装模块。

    第10章节通过模仿一个商业App,从零开始搭建一个项目,使用了前面9个章节所学内容,让我们所学知识点能达到融会贯通的地步,进一步熟练掌握。有了项目经验,在真实的企业开发中也能成为一名合格的开发人员。

    行业大佬推荐

    安辉是我们团队里的的Android专家,本书讲解清晰、示例丰富,是他的倾心力作,同时也是技术经历的真实写照,能帮助大家快速提升开发经验,少走弯路。

    ------------------------------ 郭鹏 上海翼成CTO

    万丈高楼平地起,这本书带你稳扎稳打,筑造更高的Android大厦。

    ------------------------------ 徐宜生 《Android群英传》作者

    这是一本有特色的Android 入门书籍,有基础、有新特性还有实战,推荐一读。

    ------------------------------ 刘望舒《Android进阶之光》、《Android进阶解密》作者

    本书是一本非常实用的Android 入门到进阶教材,也是Android 开发者加深强化基础知识的教材,内容简明扼要,重点突出,值得大家阅读!

    ------------------------------ Tamic 美团Android高级工程师

    感谢一些人

    首先得感谢清华出版社编辑卞诚君先生,没有他的邀请就没有本书的诞生,并且在排版以及审核上花费了很多时间,因为有他的努力付出使本书能够更快的完成。

    第二个要感谢的就是我的好朋友王帅,本书的早期大纲是我们两共同完成的(后面有修改),并且计划跟我一起写这本书,但是由于个人原因放弃了。

    还要感谢王帅跟芮成兵他两担任本书的审阅工作,给本书提供了宝贵的意见,同时感谢四位行业大佬推荐,最后感谢翼成的小伙伴们,在我写书的这段时间里对我的帮助。

    封面

    封面也改了好几次,最后还是觉得这个好看,简洁明了,希望大家喜欢。

    购买

    目前已经上线了京东、天猫、当当这三个平台,有需要的小伙伴点击下面链接购买:

    京东购买地址
    天猫购买地址
    当当网购买地址

    资源与勘误

    由于技术水平有限,书中难免会有错误,欢迎大家向我反馈:androidcoder666@163.com,邮箱在沟通上难免会有延迟,大家也可以加入我创建的QQ群。

    本书互动地址

    CSDN博客:https://blog.csdn.net/lowprofile_coding

    QQ群:202928390

    微信公众号:Android开发666

    书中案例源码下载

    https://github.com/ansen666/book_source_code

    如果你想第一时间看我的后期文章,扫码关注公众号,长期推送Android开发文章、最新动态、开源项目,让你各种涨姿势。

          Android开发666 - 安卓开发技术分享
                 扫描二维码加关注
    

    Android开发666

    展开全文
  • android开发一款app的流程

    千次阅读 2019-05-27 14:49:32
    回想一下开发一款app的流程 其实对于一个程序员来说,成长最快的莫过于独立开发一款app应用,经历一下从无到有的过程,以及这个过程中需要做的,出现的问题,怎么解决的等等。 我曾独立承担过一款app开发,这里...
  • 我们知道,要做一款安卓APP,咱们得先学安卓开发语言,例如java,前端后端。那么没有这些开发语言基础,咱们怎么做呢?其实现在有比较好的开发方案就是做webAPP,咱们可以用web前端知识构建安卓客户端,用php构建...
  • 安卓app开发-01-开发工具及环境配置

    万次阅读 2018-09-18 19:23:10
    安卓app开发-01-开发工具及环境配置 请大家根据推荐指数和自己的意愿选择 使用 Android Studio 1.可以使用 Android Studio 下载地址:http://www.android-studio.org/ 配置方法我就不转载了,请参考:...
  • 安卓app后台开发

    千次阅读 2019-12-09 15:03:43
    1,appapp后台通信一般都用http协议; , 2,长连接(一直连接着):socket和websocket, 短连接(需要时才通信):http 3,app一般以HTTP的形式调用后端提供的API:输入,输出,功能 后端返回给API的格式:JSON(轻量级的数据...
  • 安卓app开发-03-项目的基本开发步骤

    万次阅读 多人点赞 2018-09-19 15:01:33
    这里分享一下开发 安卓 app 的流程,当然有些感觉不必要,其实不然,前期工作也是极为重要的额,就像开发的时候如果目标不对的话,到后期后很迷的,所以一定要提前做好规划,就像上一篇介绍的去做详细的脑图 ...
  • 修改Android app名字(Android Studio)

    万次阅读 多人点赞 2015-08-25 10:59:39
    修改res–values–strings.xml 中的app_name即可。如下:
  • 一个快速开发APP的框架:AndroidQuick

    万次阅读 2020-10-12 15:30:57
    项目地址: https://github.com/ddnosh/AndroidQuick AndroidQuick ...AndroidQuick从开发一个APP所涉及到的架构、UI、网络、数据库、工具等方面出发,给Android开发者提供一套快速开发框架,...
  • 找到应用的manifests 并,打开 app->manifests->AndroidManifests.xml 找到application中最前面的代码如下 android:allowBackup="true" android:icon="@mipmap/ic_... android:label="@string/app_name"...
  • 在AndroidManifest.xml中 第一个为图标 第二个为名字
  • 基于AndroidStudio开发今日头条新闻APP[包含 新闻-商城-地图-支付等]综合项目实战适用人群 有Android基础,Android进阶提升,Android开发者。课程简介 基于AndroidStudio开发今日头条新闻APP项目是一款真实企业项目...
  • android 开发app使用自定义字体

    千次阅读 2018-07-23 10:51:03
    Android中是可以在开发app的时候使用自定义字体的。 在开发app的时候,界面可能要使用到第三方的字体,这时候就需要执行如下操作: 1.在项目中创建font文件夹,存放第三方字体的ttf文件 2.在TextView中设置,...
  • Android基础入门教程——1.2.2 使用Android Studio开发Android APP标签(): Android基础入门教程写在前面 本节将介绍如何使用Android Studio开发Android APP,和前面Eclipse + ADT + SDK搭建Android开发环境一样...
  • https://ask.dcloud.net.cn/article/35416
  • 不是开机启动,而是平时的时候,app自己启动,要怎么做呢?是AndroidManifest.xml里面设置吗?主要是我看到好多app平时自己就启动,好像做出这样的功能。 还有就是,有没有可能自己启动时,不是调用MainActivity的...
  • //先设置代理 Properties prop = System.getProperties(); //proxyhostIPaddress String proxyHost = "localhost"; //proxyport String proxyPort = "8118";
  • android查看app日志的一个技能

    万次阅读 2017-05-05 09:50:01
    android开发时,我们在工作台上可以看到logcat日志,但是如果测试的同事跑出来bug了,但有全局捕获异常,也没有接三放的bug统计工具,我们怎么查看bug日志呢? 其实app运行在手机上logcat也一样保存了日志在手机上的...
1 2 3 4 5 ... 20
收藏数 342,844
精华内容 137,137
关键字:

安卓app开发