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