Android实战杂记

Intro

初次尝试用 Android 进行大作业,在进行的过程中学习了一些安卓的知识,现在贴下来记录一下一些比较有用的,以后可以直接作为轮子的内容。

ToolBar使用

知识点

toolbar: 因为后面还要有页使用,所以为了方便,就做成一个文件,然后include调用了。这样可以确保后面的页面都包含这个toolbar,不用写很多重复代码

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/teacher_toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:titleTextColor="@color/white"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar">

</android.support.v7.widget.Toolbar>

接下来再要使用的activity文件中调用即可

/**
* 初始化Toolbar,并设置Toolbar中的菜单与标题,并与DrawerLayout.DrawerListener相关联,设置动态图标
*/
public void initToolbar()
{
   toolbar = (Toolbar)this.findViewById(R.id.teacher_toolbar);
   toolbar.setTitle("首页");                     // 标题的文字需在setSupportActionBar之前,不然会无效
   setSupportActionBar(toolbar);
   toolbar.setBackgroundColor(getResources().getColor(R.color.primary));
   //为了生成,工具栏左上角的动态图标,要使用下面的方法
   drawer_main = (DrawerLayout) findViewById(R.id.drawer_main);
   mDrawerToggle = new ActionBarDrawerToggle(this, drawer_main, toolbar, R.string.drawer_open,
           R.string.drawer_close);
   mDrawerToggle.syncState();
   drawer_main.setDrawerListener(mDrawerToggle);
}

最后运行就可以看到自己的Toolbar了
效果图:
这里写图片描述

AsyncTask 使用

在项目中需要用到一些API的调用,于是我们首先想到通过发送http请求进行
但是在进行中发现Android不支持主线程发送http请求,那么我们可以自己开启一个线程进行调用。但是我在这里希望做到一个回调的效果。于是在这里使用到了这个AsyncTask

首先简单介绍一下AsyncTask实现的原理,和适用的优缺点

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

使用的优点:
- 简单,快捷
- 过程可控

使用的缺点:
- 在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.
- Handler异步实现的原理和适用的优缺点

AsyncTask定义了三种泛型类型 Params,Progress和Result。
- Params 启动任务执行的输入参数,比如HTTP请求的URL。
- Progress 后台任务执行的百分比。
- Result 后台执行任务最终返回的结果,比如String。

使用过AsyncTask的同学都知道一个异步加载数据最少要重写以下这两个方法:
- doInBackground(Params…) //后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
- onPostExecute(Result) //相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

那么回到我们的项目,我们的项目需要通过AsyncTask来发送Http请求,得到结果后,通知它的Handler去进行页面的更新

于是我们的代码如下
LoginService.java

package wjw.nju.gitlab_android.apiservice;

import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;

import org.json.JSONException;
import org.json.JSONObject;

import wjw.nju.gitlab_android.apiservice.apiVO.LoginVO;
import wjw.nju.gitlab_android.util.APIHttpRequestUtil;

/**
 * Created by wangjiawei on 2017/5/31.
 */

public class LoginService extends AsyncTask<String, String ,String>{

    Handler mhandler;
    String username;
    String password;

    public LoginService(Handler handler,String username,String password){
        this.mhandler = handler;
        this.username = username;
        this.password = password;

    }


    @Override
    protected String doInBackground(String... params) {
        String re = null;
        try {
            JSONObject js = new JSONObject();
            js.put("username",username);
            js.put("password",password);
            re = APIHttpRequestUtil.postJSON(APIConfig.LOGIN_SERVICE,js);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return re;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Message msg = mhandler.obtainMessage();
        LoginVO loginVO = null;
        if(result.equals("")){
            loginVO = new LoginVO(LoginVO.LoginState.LOGIN_FAILURE);
        }else{
            try {
                JSONObject jsonObject = new JSONObject(result);
                loginVO = new LoginVO(LoginVO.LoginState.LOGIN_SUCCESS);
                loginVO.setUsername(jsonObject.getString("username"));
                loginVO.setName(jsonObject.getString("name"));
                loginVO.setType(LoginVO.LoginType.valueOf(jsonObject.getString("type")));
                loginVO.setAvatar(jsonObject.getString("avatar"));
                loginVO.setGender(LoginVO.Gender.valueOf(jsonObject.getString("gender")));
                loginVO.setEmail(jsonObject.getString("email"));
                loginVO.setPassword(password);
                if(loginVO.getType().equals(LoginVO.LoginType.student)){
                    loginVO.setS_git_id(jsonObject.getInt("gitId")+"");
                    loginVO.setS_number(jsonObject.getString("number"));
                }else if(loginVO.getType().equals(LoginVO.LoginType.teacher)){
                    loginVO.setT_authority(jsonObject.getString("authority"));
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        msg.what = 1;
        msg.obj = loginVO;
        mhandler.sendMessage(msg);
    }

}

我在这个过程中进行了一个封装操作,需要传入handler
然后重写了doInBackground以及onPostExecute方法。第一个方法是异步处理的方法,处理完成后自动进入后面的方法,在后面的操作中我们把自己想传的数据传入handler中,最后调用

mhandler.sendMessage(msg);

来通知handler进行改变

调用方法如下

private void login(){
    String username = et_name.getText().toString();
    String password = et_pass.getText().toString();
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            LoginVO loginVO = (LoginVO) msg.obj;
            if(loginVO.getLogin_state().equals(LoginVO.LoginState.LOGIN_FAILURE))
                Toast.makeText(MainActivity.this, R.string.login_fail, Toast.LENGTH_SHORT).show();
            else{
                Intent intent = null;
                if(loginVO.getType().equals(LoginVO.LoginType.teacher)) {
                    intent = new Intent(MainActivity.this, MenuActivity.class);
                }else if(loginVO.getType().equals(LoginVO.LoginType.student)){
                    intent = new Intent(MainActivity.this, MenuActivity.class);
                }
                Bundle mBundle = new Bundle();
                mBundle.putSerializable(LOGIN_KEY,loginVO);
                intent.putExtras(mBundle);
                startActivity(intent);
            }
        }
    };
    LoginService loginService = new LoginService(handler,username,password);
    loginService.execute();
}

我们把需要的数据传入,handler中进行方法的重写,进行收取到界面信息后的处理,然后调用execute()方法就可以启动整个异步线程。

Android发送json格式的http请求

之前发现需要发送http请求,就直接在网上搜索了一下,发现都是键值对形式传入数据,后来终于发现了一个json格式的请求,贴在下面。

post方法

public static String postJSON(String address_Http, JSONObject strJson) {

    String returnLine = "";
    try {
        System.out.println("**************开始http通讯**************");
        System.out.println("**************调用的接口地址为**************" + address_Http);
        System.out.println("**************请求发送的数据为**************" + strJson);

        URL my_url = new URL(address_Http);
        HttpURLConnection connection = (HttpURLConnection) my_url.openConnection();
        connection.setDoOutput(true);

        connection.setDoInput(true);

        connection.setRequestMethod("POST");

        connection.setUseCaches(false);

        connection.setInstanceFollowRedirects(true);

        connection.setRequestProperty("Content-Type", "application/json");

        connection.connect();
        DataOutputStream out = new DataOutputStream(connection

                .getOutputStream());

        byte[] content = strJson.toString().getBytes("utf-8");

        out.write(content, 0, content.length);
        out.flush();
        out.close(); // flush and close

        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));

        //StringBuilder builder = new StringBuilder();

        String line = "";

        System.out.println("Contents of post request start");

        while ((line = reader.readLine()) != null) {
            // line = new String(line.getBytes(), "utf-8");
            returnLine += line;

            System.out.println(line);

        }

        System.out.println("Contents of post request ends");

        reader.close();
        connection.disconnect();
        System.out.println("========返回的结果的为========" + returnLine);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return returnLine;
}

Get请求

public static String getJSON(String address_Http, JSONObject strJson) {
    String returnLine = "";
    try {
        System.out.println("**************开始http通讯**************");
        System.out.println("**************调用的接口地址为**************" + address_Http);
        System.out.println("**************请求发送的数据为**************" + strJson);
        System.out.println("**************请求头部的token为************" + HeaderToken);
        URL my_url = new URL(address_Http);
        HttpURLConnection connection = (HttpURLConnection) my_url.openConnection();

        connection.setRequestMethod("GET");

        connection.setDoInput(true);

        connection.setUseCaches(false);

        connection.setInstanceFollowRedirects(true);

        connection.setRequestProperty("Content-Type", "application/json");
        connection.connect();

        returnLine = new String(getBytesByInputStream(connection.getInputStream()), "UTF-8");

        System.out.println("========返回的结果的为========" + returnLine);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return returnLine;
}

End

以上是进行Android实践作业中的一些杂记
最后附上Github地址: https://github.com/WJerry0227/GitLab_Androidapp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值