1. WelcomeActivity
package comi.example.liy.firstbasicproject.ui.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import comi.example.liy.firstbasicproject.R;
import comi.example.liy.firstbasicproject.persist.Settings;
/**
* Created by liy on 2018-03-12.
*/
public class WelcomeActivity extends Activity {
private static final String TAG = WelcomeActivity.class.getName();
private Intent intent;
private Settings settings;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.v("lfeCycle",TAG+"***"+"onCreate");
super.onCreate(savedInstanceState);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_welcome);
settings = Settings.getInstance(this);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if(settings.getUserId().equals("")){
intent = new Intent(WelcomeActivity.this, LoginActivity.class);
}else {
intent = new Intent(WelcomeActivity.this, MainActivity.class);
}
startActivity(intent);
finish();
}
}, 1500);
}
}
1.1 activity_welcome.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">
</LinearLayout>
1.2 Settings類
package comi.example.liy.firstbasicproject.persist;
import android.content.Context;
import android.content.SharedPreferences;
/**
* Created by liy on 2017-09-22.
*1、SharedPreferences只能保存簡單類型的數(shù)據(jù),例如四種基本類型(int含蓉,float鞭执,long伴找,boolean)+String抖誉。
* 如果需要存取比較復(fù)雜的數(shù)據(jù)類型比如類或者圖像我磁,則需要對這些數(shù)據(jù)進(jìn)行編碼,通常將其轉(zhuǎn)換成Base64編碼,然后將轉(zhuǎn)換后的數(shù)據(jù)以字符串的形式保存在XML文件中。
*2、存儲對象:
* 方法一:fastJson/Gson/Jackson將對象轉(zhuǎn)換成字符串,然后再保存篙螟。
* 方法二:ObjectOutputStream將對象轉(zhuǎn)化成流,base64將流轉(zhuǎn)成字符串蕾久,然后再保存障簿。
*/
public class Settings {
private static Settings preferences;
private static SharedPreferences sharedPreferences;//SharedPreferences是Android平臺上一個輕量級的存儲類西篓,用來保存應(yīng)用的一些常用配置
private static final String PREFERENCE = "settings";
private static final String USER_ID="user_id";//用戶工號
public static Settings getInstance(Context context){
if(preferences==null){
preferences=new Settings(context);
}
return preferences;
}
public Settings(Context context){
sharedPreferences=context.getSharedPreferences(PREFERENCE,Context.MODE_PRIVATE);
}
public synchronized void setUserId(String userId){
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString(USER_ID,userId);
editor.commit();
}
public synchronized String getUserId(){
return sharedPreferences.getString(USER_ID,"");
}
}
2. LoginActivity
package comi.example.liy.firstbasicproject.ui.activity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.Window;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import comi.example.liy.firstbasicproject.R;
import comi.example.liy.firstbasicproject.management.DataManagement;
import comi.example.liy.firstbasicproject.persist.Settings;
import comi.example.liy.firstbasicproject.tool.ToastUtil;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.CLOSED;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.CONNECT_EXCEPTION;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.EXCEPTION_RESULT_CODE;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.LOGIN_SUCCESS;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.SOCKET_TIMEOUT;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.UNKNOWN_ERROR;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.UNKNOWN_HOST;
/**
* Created by liy on 2018-03-12.
*/
public class LoginActivity extends Activity {
private static final String TAG = LoginActivity.class.getName();
private LoginActivity activity;
private Settings settings;
public DataManagement dataManagement;
private Handler handler;
private ImageView ivSetting;
private TextView tvUserId;
private Button btnLogin;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_login);
initViews();
initData();
initHandler();
initListeners();
}
@Override
public void onBackPressed() {
//返回手機(jī)的主屏幕
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
private void initViews(){
ivSetting = (ImageView) findViewById(R.id.activity_login_ivSetting);
tvUserId= (AutoCompleteTextView)findViewById(R.id.activity_login_tvUserId);
btnLogin = (Button)findViewById(R.id.activity_login_btnLogin);
}
private void initData(){
activity = this;
settings = Settings.getInstance(this);
dataManagement = DataManagement.getFyDataManagement(this);
tvUserId.setText(settings.getUserId());
}
private void initHandler(){
handler = new Handler(){
public void handleMessage(Message message) {
switch (message.what) {
case LOGIN_SUCCESS: //登錄成功
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
break;
case EXCEPTION_RESULT_CODE: //登錄異常結(jié)果碼
Toast.makeText(activity,activity.getString(R.string.error_result_code), Toast.LENGTH_SHORT).show();
break;
case CLOSED:
Toast.makeText(activity,activity.getString(R.string.closed), Toast.LENGTH_SHORT).show();
break;
case SOCKET_TIMEOUT:
Toast.makeText(activity,activity.getString(R.string.SocketTimeoutException), Toast.LENGTH_SHORT).show();
break;
case CONNECT_EXCEPTION:
Toast.makeText(activity,activity.getString(R.string.ConnectException), Toast.LENGTH_SHORT).show();
break;
case UNKNOWN_HOST:
Toast.makeText(activity,activity.getString(R.string.UnknownHostException), Toast.LENGTH_SHORT).show();
break;
case UNKNOWN_ERROR:
Toast.makeText(activity,activity.getString(R.string.UnknownError), Toast.LENGTH_SHORT).show();
break;
default:
break;
}
super.handleMessage(message);
}
};
}
private void initListeners(){
ivSetting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this,SettingActivity.class);
startActivity(intent);
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String userId = tvUserId.getText().toString();
if(userId.equals("")){
ToastUtil.show(activity,getString(R.string.please_input_userId));
}else {
dataManagement.UserLoginVerify(userId,handler,settings);
}
}
});
}
public Handler getHandler() {
return handler;
}
}
2.1 activity_login.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:padding="@dimen/margin_1"
android:background="@drawable/background_shape">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="@integer/weight_1"
android:orientation="horizontal"
android:layout_gravity="right">
<ImageView
android:id="@+id/activity_login_ivSetting"
android:layout_width="@dimen/setting_sys"
android:layout_height="@dimen/setting_sys"
android:src="@drawable/system_setting"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="@integer/weight_7"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="@+id/activity_login_tvUserId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/please_input_userId"
android:inputType="textPersonName"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/activity_login_etpassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/please_input_password"
android:imeActionId="6"
android:imeActionLabel="Sign in"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/activity_login_btnLogin"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/btn_login"
android:textStyle="bold"
android:background="@drawable/selector_button"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="@integer/weight_2"/>
</LinearLayout>
2.2 background_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
//設(shè)置邊框內(nèi)角弧度
<corners android:radius="3dp"/>
//設(shè)置邊框以內(nèi)顏色
<solid android:color="@color/white"/>
//設(shè)置組件邊框
<stroke
android:color="@color/black"
android:width="1dp"
/>
//設(shè)置組件里內(nèi)容距離組件內(nèi)邊緣的間距
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp"
/>
<gradient
android:startColor="#ffffff"
android:endColor="@color/blue_1"
android:useLevel="true"
android:angle="45"
android:type="linear"
android:gradientRadius="180"/>
</shape>
2.3 colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="white">#ffffff</color>
<color name="white_alpha_1">#77ffffff</color>
<color name="white_alpha_2">#11ffffff</color>
<color name="gray_1">#222222</color>
<color name="gray_1_alpha">#99222222</color>
<color name="gray_2">#cccccc</color>
<color name="blue_1">#149FEB</color>
<color name="blue_1_alpha">#99149FEB</color>
<color name="blue_2">#C9D5EB</color>
<color name="blue_3">#E5EBF5</color>
<color name="green_1">#2fba2f</color>
<color name="red">#ff0000</color>
<color name="green">#00ff00</color>
<color name="blue">#0000ff</color>
<color name="black">#000001</color>
<color name="gray">#222222</color>
<color name="color_dark_grey">#808080</color>
<color name="color_red_2">#f00</color>
<color name="color_red_3">#f5f</color>
<color name="color_orange">#f44</color>
<color name="color_green_2">#aff</color>
<color name="color_yellow_2">#ff0</color>
<color name="salary_blue">#077874</color>
<color name="lightblue">#77ffffff</color>
<color name="line_grey">#77ffffff</color>
<color name="whites">#FFFFFF</color> <!--白色 -->
<color name="ivory">#FFFFF0</color> <!--象牙色 -->
<color name="lightyellow">#FFFFE0</color> <!--亮黃色 -->
<color name="yellow">#FFFF00</color> <!--黃色 -->
<color name="snow">#FFFAFA</color> <!--雪白色 -->
<color name="floralwhite">#FFFAF0</color> <!--花白色 -->
<color name="lemonchiffon">#FFFACD</color> <!--檸檬綢色 -->
<color name="cornsilk">#FFF8DC</color> <!--米綢色 -->
<color name="seashell">#FFF5EE</color> <!--海貝色 -->
<color name="lavenderblush">#FFF0F5</color> <!--淡紫紅 -->
<color name="papayawhip">#FFEFD5</color> <!--番木色 -->
<color name="blanchedalmond">#FFEBCD</color> <!--白杏色 -->
<color name="mistyrose">#FFE4E1</color> <!--淺玫瑰色 -->
<color name="bisque">#FFE4C4</color> <!--桔黃色 -->
<color name="moccasin">#FFE4B5</color> <!--鹿皮色 -->
<color name="navajowhite">#FFDEAD</color> <!--納瓦白 -->
<color name="peachpuff">#FFDAB9</color> <!--桃色 -->
<color name="gold">#FFD700</color> <!--金色 -->
<color name="pink">#FFC0CB</color> <!--粉紅色 -->
<color name="lightpink">#FFB6C1</color> <!--亮粉紅色 -->
<color name="orange">#FFA500</color> <!--橙色 -->
<color name="lightsalmon">#FFA07A</color> <!--亮肉色 -->
<color name="darkorange">#FF8C00</color> <!--暗桔黃色 -->
<color name="coral">#FF7F50</color> <!--珊瑚色 -->
<color name="hotpink">#FF69B4</color> <!--熱粉紅色 -->
<color name="tomato">#FF6347</color> <!--西紅柿色 -->
<color name="orangered">#FF4500</color> <!--紅橙色 -->
<color name="deeppink">#FF1493</color> <!--深粉紅色 -->
<color name="fuchsia">#FF00FF</color> <!--紫紅色 -->
<color name="magenta">#FF00FF</color> <!--紅紫色 -->
<color name="reds">#FF0000</color> <!--紅色 -->
<color name="oldlace">#FDF5E6</color> <!--老花色 -->
<color name="lightgoldenrodyellow">#FAFAD2</color> <!--亮金黃色 -->
<color name="linen">#FAF0E6</color> <!--亞麻色 -->
<color name="antiquewhite">#FAEBD7</color> <!--古董白 -->
<color name="salmon">#FA8072</color> <!--鮮肉色 -->
<color name="ghostwhite">#F8F8FF</color> <!--幽靈白 -->
<color name="mintcream">#F5FFFA</color> <!--薄荷色 -->
<color name="whitesmoke">#F5F5F5</color> <!--煙白色 -->
<color name="beige">#F5F5DC</color> <!--米色 -->
<color name="wheat">#F5DEB3</color> <!--淺黃色 -->
<color name="sandybrown">#F4A460</color> <!--沙褐色 -->
<color name="azure">#F0FFFF</color> <!--天藍(lán)色 -->
<color name="honeydew">#F0FFF0</color> <!--蜜色 -->
<color name="aliceblue">#F0F8FF</color> <!--艾利斯蘭 -->
<color name="khaki">#F0E68C</color> <!--黃褐色 -->
<color name="lightcoral">#F08080</color> <!--亮珊瑚色 -->
<color name="palegoldenrod">#EEE8AA</color> <!--蒼麒麟色 -->
<color name="violet">#EE82EE</color> <!--紫羅蘭色 -->
<color name="darksalmon">#E9967A</color> <!--暗肉色 -->
<color name="lavender">#E6E6FA</color> <!--淡紫色 -->
<color name="lightcyan">#E0FFFF</color> <!--亮青色 -->
<color name="burlywood">#DEB887</color> <!--實木色 -->
<color name="plum">#DDA0DD</color> <!--洋李色 -->
<color name="gainsboro">#DCDCDC</color> <!--淡灰色 -->
<color name="crimson">#DC143C</color> <!--暗深紅色 -->
<color name="palevioletred">#DB7093</color> <!--蒼紫羅蘭色 -->
<color name="goldenrod">#DAA520</color> <!--金麒麟色 -->
<color name="orchid">#DA70D6</color> <!--淡紫色 -->
<color name="thistle">#D8BFD8</color> <!--薊色 -->
<color name="lightgray">#D3D3D3</color> <!--亮灰色 -->
<color name="lightgrey">#D3D3D3</color> <!--亮灰色 -->
<color name="tan">#D2B48C</color> <!--茶色 -->
<color name="chocolate">#D2691E</color> <!--巧可力色 -->
<color name="peru">#CD853F</color> <!--秘魯色 -->
<color name="indianred">#CD5C5C</color> <!--印第安紅 -->
<color name="mediumvioletred">#C71585</color> <!--中紫羅蘭色 -->
<color name="silver">#C0C0C0</color> <!--銀色 -->
<color name="darkkhaki">#BDB76B</color> <!--暗黃褐色-->
<color name="rosybrown">#BC8F8F</color> <!--褐玫瑰紅 -->
<color name="mediumorchid">#BA55D3</color> <!--中粉紫色 -->
<color name="darkgoldenrod">#B8860B</color> <!--暗金黃色 -->
<color name="firebrick">#B22222</color> <!--火磚色 -->
<color name="powderblue">#B0E0E6</color> <!--粉藍(lán)色 -->
<color name="lightsteelblue">#B0C4DE</color> <!--亮鋼蘭色-->
<color name="paleturquoise">#AFEEEE</color> <!--蒼寶石綠 -->
<color name="greenyellow">#ADFF2F</color> <!--黃綠色 -->
<color name="lightblues">#ADD8E6</color> <!--亮藍(lán)色 -->
<color name="darkgray">#A9A9A9</color> <!--暗灰色 -->
<color name="darkgrey">#A9A9A9</color> <!--暗灰色 -->
<color name="brown">#A52A2A</color> <!--褐色 -->
<color name="sienna">#A0522D</color> <!--赭色 -->
<color name="darkorchid">#9932CC</color> <!--暗紫色 -->
<color name="palegreen">#98FB98</color> <!--蒼綠色 -->
<color name="darkviolet">#9400D3</color> <!--暗紫羅蘭色 -->
<color name="mediumpurple">#9370DB</color> <!--中紫色 -->
<color name="lightgreen">#90EE90</color> <!--亮綠色 -->
<color name="darkseagreen">#8FBC8F</color> <!--暗海蘭色 -->
<color name="saddlebrown">#8B4513</color> <!--重褐色 -->
<color name="darkmagenta">#8B008B</color> <!--暗洋紅 -->
<color name="darkred">#8B0000</color> <!--暗紅色 -->
<color name="blueviolet">#8A2BE2</color> <!--紫羅蘭藍(lán)色 -->
<color name="lightskyblue">#87CEFA</color> <!--亮天藍(lán)色 -->
<color name="skyblue">#87CEEB</color> <!--天藍(lán)色 -->
<color name="grays">#808080</color> <!--灰色 -->
<color name="grey">#808080</color> <!--灰色 -->
<color name="olive">#808000</color> <!--橄欖色 -->
<color name="purple">#800080</color> <!--紫色 -->
<color name="maroon">#800000</color> <!--粟色 -->
<color name="aquamarine">#7FFFD4</color> <!--碧綠色 -->
<color name="chartreuse">#7FFF00</color> <!--黃綠色 -->
<color name="lawngreen">#7CFC00</color> <!--草綠色 -->
<color name="mediumslateblue">#7B68EE</color> <!--中暗藍(lán)色 -->
<color name="lightslategray">#778899</color> <!--亮藍(lán)灰 -->
<color name="lightslategrey">#778899</color> <!--亮藍(lán)灰 -->
<color name="slategray">#708090</color> <!--灰石色 -->
<color name="slategrey">#708090</color> <!--灰石色 -->
<color name="olivedrab">#6B8E23</color> <!--深綠褐色 -->
<color name="slateblue">#6A5ACD</color> <!--石藍(lán)色 -->
<color name="dimgray">#696969</color> <!--暗灰色 -->
<color name="dimgrey">#696969</color> <!--暗灰色 -->
<color name="mediumaquamarine">#66CDAA</color> <!--中綠色 -->
<color name="cornflowerblue">#6495ED</color> <!--菊蘭色 -->
<color name="cadetblue">#5F9EA0</color> <!--軍蘭色 -->
<color name="darkolivegreen">#556B2F</color> <!--暗橄欖綠-->
<color name="indigo">#4B0082</color> <!--靛青色 -->
<color name="mediumturquoise">#48D1CC</color> <!--中綠寶石 -->
<color name="darkslateblue">#483D8B</color> <!--暗灰藍(lán)色 -->
<color name="steelblue">#4682B4</color> <!--鋼蘭色 -->
<color name="royalblue">#4169E1</color> <!--皇家藍(lán) -->
<color name="turquoise">#40E0D0</color> <!--青綠色 -->
<color name="mediumseagreen">#3CB371</color> <!--中海藍(lán) -->
<color name="limegreen">#32CD32</color> <!--橙綠色 -->
<color name="darkslategray">#2F4F4F</color> <!--暗瓦灰色 -->
<color name="darkslategrey">#2F4F4F</color> <!--暗瓦灰色 -->
<color name="seagreen">#2E8B57</color> <!--海綠色 -->
<color name="forestgreen">#228B22</color> <!--森林綠 -->
<color name="lightseagreen">#20B2AA</color> <!--亮海藍(lán)色 -->
<color name="dodgerblue">#1E90FF</color> <!--閃蘭色 -->
<color name="midnightblue">#191970</color> <!--中灰蘭色 -->
<color name="aqua">#00FFFF</color> <!--淺綠色 -->
<color name="cyan">#00FFFF</color> <!--青色 -->
<color name="springgreen">#00FF7F</color> <!--春綠色 -->
<color name="lime">#00FF00</color> <!--酸橙色 -->
<color name="mediumspringgreen">#00FA9A</color> <!--中春綠色 -->
<color name="darkturquoise">#00CED1</color> <!--暗寶石綠 -->
<color name="deepskyblue">#00BFFF</color> <!--深天藍(lán)色 -->
<color name="darkcyan">#008B8B</color> <!--暗青色 -->
<color name="teal">#008080</color> <!--水鴨色 -->
<color name="greens">#008000</color> <!--綠色 -->
<color name="darkgreen">#006400</color> <!--暗綠色 -->
<color name="blues">#0000FF</color> <!--藍(lán)色 -->
<color name="mediumblue">#0000CD</color> <!--中蘭色 -->
<color name="darkblue">#00008B</color> <!--暗藍(lán)色 -->
<color name="navy">#000080</color> <!--海軍色 -->
<color name="blacks">#000000</color> <!--黑色 -->
<color name="work_green">#a8cf8d</color>
<color name="error_pink">#f7caac</color>
<color name="repair_gray">#bebebe</color>
<color name="idle_yellow">#fdd866</color>
<color name="halting_red">#fd3301</color>
<color name="fy_white">#fdfdfe</color>
<color name="fy_black">#000001</color>
<color name="fy_red">#ec1c24</color>
<color name="fy_yellow">#fdec01</color>
<color name="fy_gray">#7e7e7f</color>
<color name="fy_blue_bg">#00afef</color>
<color name="fy_blue_text">#22c4ec</color>
<color name="fy_blue_bt">#5180b9</color>
<color name="fy_blue">#00a1e7</color>
<color name="fy_fluorescent_green">#00fd01</color>
<color name="fy_green">#22b04c</color>
<color name="enabled_false">#77ffffff</color>
<color name="pressed_false">#4BAE4F</color>
<color name="pressed_true">#FFCD41</color>
<color name="selected_false">#6A5ACD</color>
<color name="selected_true">#DAA520</color>
<color name="colorTitleGray">#808080</color>
</resources>
3. MainActivity
package comi.example.liy.firstbasicproject.ui.activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import comi.example.liy.firstbasicproject.R;
import comi.example.liy.firstbasicproject.entityClass.TestDate;
import comi.example.liy.firstbasicproject.management.DataManagement;
import comi.example.liy.firstbasicproject.persist.Settings;
import comi.example.liy.firstbasicproject.tool.ToastUtil;
import comi.example.liy.firstbasicproject.ui.fragment.ReworkFragment;
import comi.example.liy.firstbasicproject.ui.fragment.SixSFragment;
import comi.example.liy.firstbasicproject.ui.fragment.WorkFragment;
import comi.example.liy.firstbasicproject.ui.fragment.YieldFragment;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.CLOSED;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.CONNECT_EXCEPTION;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.EXCEPTION_RESULT_CODE;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.LOGOUT_SUCCESS;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.SOCKET_TIMEOUT;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.UNKNOWN_ERROR;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.UNKNOWN_HOST;
public class MainActivity extends FragmentActivity {
private MainActivity activity;
public DataManagement dataManagement;
private Settings settings;
private Handler handler;
private Button btnOthers;
private TextView topTitle;
private Button btnCancellation;
private boolean activityActive = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initData();
initHandler();
initListeners();
}
@Override
protected void onRestart() {
super.onRestart();
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
activityActive = true;
super.onResume();
}
@Override
protected void onPause() {
activityActive = false;
super.onPause();
}
@Override
protected void onStop() {
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onBackPressed() {
//返回手機(jī)的主屏幕
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
/**
* 初始化組件
*/
private void initViews(){
btnOthers = (Button)findViewById(R.id.main_top_btnOthers);
topTitle = (TextView)findViewById(R.id.main_top_tvTitle);
btnCancellation = (Button)findViewById(R.id.main_top_btnCancellation);
}
/**
* 初始化數(shù)據(jù)
*/
private void initData(){
activity = this;
settings = Settings.getInstance(this);
dataManagement = DataManagement.getFyDataManagement(this);
}
private void initHandler(){
handler = new Handler() {
public void handleMessage(Message msg) {
if (activityActive) {
switch (msg.what) {
case SOCKET_TIMEOUT:
//連接超時警告框
warningDialog(activity.getString(R.string.SocketTimeoutException),activity.getString(R.string.SocketTimeoutException_des));
break;
case CONNECT_EXCEPTION:
//連接失敗警告框
warningDialog(activity.getString(R.string.ConnectException),activity.getString(R.string.ConnectException_des));
break;
case UNKNOWN_HOST:
//無法解析主機(jī)警告框
warningDialog(activity.getString(R.string.UnknownHostException),activity.getString(R.string.UnknownHostException_des));
break;
case UNKNOWN_ERROR:
//未知錯誤警告框
warningDialog(activity.getString(R.string.UnknownError),activity.getString(R.string.UnknownError_eds));
break;
case CLOSED:
//主動取消警告框
warningDialog(activity.getString(R.string.closed),activity.getString(R.string.closed_des));
break;
case EXCEPTION_RESULT_CODE:
ToastUtil.show(activity,activity.getString(R.string.error_result_code));
break;
case LOGOUT_SUCCESS:
settings.setUserId("");
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
intent.putExtra("lastActivityName","MainActivity");
startActivity(intent);
break;
default:
break;
}
}
}
};
}
private void initListeners(){
btnOthers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,HomeActivity.class);
startActivity(intent);
}
});
btnCancellation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showAccountCancelationDialog();
}
});
}
public Handler getHandler() {
return handler;
}
/**
* 賬號注銷
*/
private void showAccountCancelationDialog(){
final AlertDialog.Builder accountCancelationDialog = new AlertDialog.Builder(MainActivity.this);
accountCancelationDialog.setIcon(R.drawable.ic_acccount);
accountCancelationDialog.setTitle(R.string.account_cancellation_title);
accountCancelationDialog.setMessage(R.string.account_cancellation_message);
accountCancelationDialog.setPositiveButton(R.string.btn_sure,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dataManagement.UserLogoutVerify(handler);
}
});
accountCancelationDialog.setNegativeButton(R.string.btn_cancel,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
accountCancelationDialog.show();// 顯示
}
/*********************警告或提示類型的彈窗,只起提示作用不做數(shù)據(jù)處理***************/
private AlertDialog alertDialog = null;
public void warningDialog(String title, String message) {
if(alertDialog == null){
alertDialog = new AlertDialog.Builder(this,R.style.Theme_AppCompat_Light_Dialog_Alert)
.setTitle(title)
.setMessage(message)
.setPositiveButton(R.string.btn_sure, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}else{
if(alertDialog.isShowing()){
}else{
alertDialog.show();
}
}
}
}
3.1 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/activity_main_top" />
<FrameLayout
android:id="@+id/activity_main_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="@integer/weight_1">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="@+id/activity_main_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation" />
</LinearLayout>
3.2 activity_main.xml
<?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="43dp"
android:background="@color/colorTitleGray">
<TextView
android:id="@+id/main_top_tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:text="首頁"
android:textColor="@color/white"
android:textSize="20sp"/>
<Button
android:id="@+id/main_top_btnCancellation"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:background="@drawable/ic_cancellation"/>
</RelativeLayout>
3.3 ic_cancellation.xml
<vector
android:height="24dp"
android:viewportHeight="1024.0"
android:viewportWidth="1024.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#ff0000"
android:pathData="M737,210.2C733.3,210.4 732.4,210.3 728.7,210.9 721.8,211.9 715,214.1 708.8,217.3 702.6,220.5 697,224.7 692.1,229.7 688.2,233.7 684.9,238.3 682.1,243.1 674,257.9 671.9,275.6 676.6,291.8 678.9,299.9 682.8,307.5 688,314 690.3,316.9 691,317.5 693.6,320.2L696.7,323C710.6,334.8 723.4,347.6 734.9,361.6 762.9,395.8 782.8,436.2 792.7,479.3 800.7,514.2 802.1,550.6 796.9,586.1 791.5,622.8 778.9,658.5 760.1,690.5 745.4,715.3 727,737.8 705.7,757.2 685,775.9 661.6,791.7 636.4,803.8 609,817 579.5,825.7 549.3,829.5 515,834 479.8,832.2 446.1,824.3 410.9,816.1 377.3,801.2 347.7,780.6 315.7,758.3 288.4,729.5 267.7,696.5 246.5,662.7 232.5,624.4 226.9,584.7 220.7,541.2 224.6,496.5 238.2,454.7 248.7,422.4 264.9,392 286,365.3 295.8,353 306.7,341.5 318.3,330.8 322.3,327.3 326.3,323.9 330.2,320.4 332.8,317.7 333.5,317.1 335.8,314.2 341,307.6 344.9,300 347.2,292 349.4,283.9 350.1,275.4 349.2,267.1 348.4,260.1 346.4,253.3 343.4,247 340.4,240.7 336.4,234.9 331.5,229.9 319.8,217.8 303.4,210.8 286.5,210.5 281,210.4 275.4,211.1 270,212.4 263.2,214.1 256.7,217 250.8,220.7 245.6,224.1 241,228.4 236.3,232.5 229.7,238.3 223.2,244.4 217,250.7 191.4,276.4 169.2,305.4 151.2,336.8 120.3,390.6 101.8,451.2 97.2,513 92.5,574.8 101.9,637.6 124.4,695.4 140.3,735.9 162.6,773.8 190.1,807.5 216.7,839.9 248.1,868.4 283.1,891.4 322.5,917.4 366.3,936.5 412.1,947.8 465.5,960.9 521.3,963.4 575.7,955.1 626.1,947.3 674.9,930.2 719.1,904.8 760.4,881.1 797.5,850.3 828.4,814.2 853.9,784.3 875.2,750.8 891.3,715 922.8,645 934.4,566.4 924.5,490.3 918.7,445 905.3,400.7 885.1,359.7 868.3,325.8 846.9,294.2 821.6,266.1 811.5,254.8 800.7,244.2 789.5,234 786.2,231.1 782.8,228.2 779.5,225.4 776.6,223 775.9,222.4 772.8,220.4 766.9,216.6 760.4,213.8 753.6,212.1 749.5,211.1 745.4,210.6 741.2,210.3 739.8,210.2 738.4,210.2 737,210.2M576,576C576,593 569.3,609.2 557.3,621.2 545.3,633.2 529,640 512,640 495,640 478.8,633.2 466.8,621.2 454.8,609.2 448,593 448,576L448,128C448,111 454.8,94.8 466.8,82.7 478.8,70.7 495,64 512,64 529,64 545.3,70.7 557.3,82.7 569.3,94.8 576,111 576,128L576,576Z"/>
</vector>
3.3 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="closed">主動取消!</string>
<string name="closed_des">Network request active shutdown</string>
<string name="SocketTimeoutException">連接超時澄暮!</string>
<string name="SocketTimeoutException_des">Network request connection timeout</string>
<string name="ConnectException">服務(wù)器連接失敗!</string>
<string name="ConnectException_des">Network request connection failed</string>
<string name="UnknownHostException">無法解析主機(jī)碎乃!</string>
<string name="UnknownHostException_des">The network request cannot resolve the host</string>
<string name="UnknownError">未知錯誤佛南!</string>
<string name="UnknownError_eds">Network request unknown error</string>
<resources>
4. DataManagement管理類
package comi.example.liy.firstbasicproject.management;
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import comi.example.liy.firstbasicproject.entityClass.ResponseResult;
import comi.example.liy.firstbasicproject.entityClass.User;
import comi.example.liy.firstbasicproject.persist.Settings;
import comi.example.liy.firstbasicproject.remote.HttpUrl;
import comi.example.liy.firstbasicproject.tool.LoggerUtil;
import comi.example.liy.firstbasicproject.util.GlobalConstant;
import comi.example.liy.firstbasicproject.util.Okhttp;
import okhttp3.FormBody;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.EXCEPTION_RESULT_CODE;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.LOGIN_SUCCESS;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.LOGOUT_SUCCESS;
/**
* Created by liy on 2018-10-16 8:40
*/
public class DataManagement {
private static Activity activity;
private HttpUrl httpUrl;
private LoggerUtil loggerUtil;
private GlobalConstant globalConstant;
private String userId = "";
private String userName = "";
private String userDept = "";
private Settings settings;
private boolean isTest = true;
private DataManagement(Context context){
httpUrl = HttpUrl.getHttpUrl();
loggerUtil = LoggerUtil.getLoggerUtil();
globalConstant = GlobalConstant.getGlobalConstant();
settings = Settings.getInstance(context);
}
private static DataManagement dataManagement;
public static DataManagement getFyDataManagement(final Context context){
if(dataManagement==null){
dataManagement = new DataManagement(context);
}
activity = (Activity)context;
return dataManagement;
}
/**
* 用戶登錄:
* @param userId
* @param handler
* @param settings
*/
public void UserLoginVerify(final String userId,final Handler handler, final Settings settings){
if(isTest){
Message message = new Message();
message.what = LOGIN_SUCCESS;//登錄成功
handler.sendMessage(message);
return;
}
String loginUrl = httpUrl.fyLoginUrl;
loggerUtil.v("login_loginUrl",loginUrl);
Okhttp okhttp = Okhttp.getOkhttp(activity);
Okhttp.HttpBuilder builder = new Okhttp.HttpBuilder() {
@Override
public FormBody.Builder getBuilder() {
FormBody.Builder builder = new FormBody.Builder();
builder.add("userId", userId);
return builder;
}
};
Okhttp.HttpResponse response = new Okhttp.HttpResponse() {
@Override
public void onPostFinishedResponse(String response) {
loggerUtil.v("login_response",response);
}
@Override
public void onPostFinished(Object object) {
try{
User user = (User) object;
String result = user.getResult();
loggerUtil.v("login_code","結(jié)果碼"+result);
Message message = new Message();
if(result.equals("10")){
setLoginUserInfo(user,settings);
message.what = LOGIN_SUCCESS;//登錄成功
}else{
message.what = EXCEPTION_RESULT_CODE;
}
handler.sendMessage(message);
}catch (Exception e){
e.printStackTrace();
loggerUtil.v("login_error", e.getMessage().toString());
}
}
};
okhttp.OkhttpPost(loginUrl,builder,User.class,response);
}
private void setLoginUserInfo(User user,Settings settings){
userId = user.getUserId();
userName = user.getUserName();
userDept = user.getDepartmentNumber();
settings.setUserId(user.getUserId());
}
/**
* 用戶退出
* @param handler
*/
public void UserLogoutVerify(final Handler handler){
if(isTest){
Message message = new Message();
message.what = LOGOUT_SUCCESS;
handler.sendMessage(message);
return;
}
String fyLogoutUrl = httpUrl.fyLogoutUrl;
Okhttp okhttp = Okhttp.getOkhttp(activity);
Okhttp.HttpBuilder builder = new Okhttp.HttpBuilder() {
@Override
public FormBody.Builder getBuilder() {
FormBody.Builder builder = new FormBody.Builder();
builder.add("userId",userId);
return builder;
}
};
Okhttp.HttpResponse response = new Okhttp.HttpResponse() {
@Override
public void onPostFinishedResponse(String response) {
loggerUtil.v("logout_response",response);
}
@Override
public void onPostFinished(Object object) {
ResponseResult responseResult = (ResponseResult)object;
String result = "";
if(responseResult!=null){
result = responseResult.result;
}
loggerUtil.v("logout_result",result);
if(result.equals("1")){
Message message = new Message();
message.what = LOGOUT_SUCCESS;
handler.sendMessage(message);
}else {
Message message = new Message();
message.what = EXCEPTION_RESULT_CODE;
handler.sendMessage(message);
}
}
};
okhttp.OkhttpPost(fyLogoutUrl,builder,ResponseResult.class,response);
}
}
5. Okhttp封裝類
package comi.example.liy.firstbasicproject.util;
import android.content.Context;
import android.os.Message;
import android.util.Log;
import com.google.gson.Gson;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;
import comi.example.liy.firstbasicproject.ui.activity.LoginActivity;
import comi.example.liy.firstbasicproject.ui.activity.MainActivity;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.CLOSED;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.CONNECT_EXCEPTION;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.SOCKET_TIMEOUT;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.UNKNOWN_ERROR;
import static comi.example.liy.firstbasicproject.util.GlobalConstant.UNKNOWN_HOST;
/**
* Created by liy on 2018-10-16 9:04
* 網(wǎng)絡(luò)請求框架:Apache提供的HttpClient、HttpURLConnection(被OkHttp替換)恩掷、google推出的Volley框架逼争、android-async-http框架杂伟、Xutils频蛔、Retrofit
*
* json字符串->實體對象
* 1、Http Get
* 2牌借、Http Post 攜帶參數(shù):封裝onFailure()和onResponse()方法
* 3院领、基于Http的文件上傳:支持大文件下載,通過IO的方式寫文件
*
* OkHttp是一款優(yōu)秀的HTTP框架,它支持get請求和post請求蓖墅,支持基于Http的文件上傳和下載,支持加載圖片,支持下載文件透明的GZIP壓縮章姓,支持響應(yīng)緩存避免重復(fù)的網(wǎng)絡(luò)請求,支持使用連接池來降低響應(yīng)延遲問題
*OkHttp的一個高效之處在于OkHttp的任務(wù)隊列在內(nèi)部維護(hù)了一個線程池(線程池最大的好處在于通過線程復(fù)用減少非核心任務(wù)的損耗)窒舟,方便高效地執(zhí)行異步請求
*特點一:OkHttp采用Dispatcher(作為任務(wù)的派發(fā)器)技術(shù)系忙,類似于Nginx(使用了與Nginx類似的反向代理與分發(fā)技術(shù),這是典型的單生產(chǎn)者多消費者問題)惠豺,與線程池配合實現(xiàn)了高并發(fā)银还,低阻塞的運行
*特點二:Okhttp采用Deque作為緩存,按照入隊的順序先進(jìn)先出
*特點三:OkHttp最出彩的地方就是在try/finally中調(diào)用了finished函數(shù)洁墙,可以主動控制等待隊列的移動蛹疯,而不是采用鎖或者wait/notify,極大減少了編碼復(fù)雜性
*缺點:OkHttp不支持優(yōu)先級請求热监、OkHttp不支持自簽名證書捺弦、OkHttp header中不能傳中文
*/
public class Okhttp {
private String aa ="";//服務(wù)器返回的字符串,如json字符串
private Object BB = new Object();//服務(wù)器回復(fù)信息轉(zhuǎn)為類
private Context activity;
private final OkHttpClient mClinet = new OkHttpClient();
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
/**
* 單例模式
*/
private static Okhttp mOkhttp;
private Okhttp(Context activity){
this.activity = activity;
}
//大多數(shù)程序只需要調(diào)用一次new OkHttp()
public static Okhttp getOkhttp(Context activity){
if (mOkhttp==null){
mOkhttp = new Okhttp(activity);
}
mOkhttp.activity = activity;
return mOkhttp;
}
public <T>T OkhttpPost(String path, HttpBuilder HttpBuilder, final Class<T> clazz , final HttpResponse httpRespone){
//創(chuàng)建okHttpClient對象孝扛,OkHttpClient配置包括代理設(shè)置列吼、超時設(shè)置(連接、讀取和寫入超時)疗琉、緩存設(shè)置等
final OkHttpClient mOkHttpClient=mClinet
.newBuilder()
.readTimeout(5000,TimeUnit.MILLISECONDS)
.connectTimeout(5000,TimeUnit.MILLISECONDS)
.writeTimeout(5000,TimeUnit.MILLISECONDS)
.build();
//創(chuàng)建一個Request:通過Request.Builder設(shè)置url(參數(shù)最起碼有個url)冈欢、method歉铝、header等參數(shù)
RequestBody formBody = HttpBuilder.getBuilder().build();//MultipartBuilder可以構(gòu)建復(fù)雜的請求體,即RequestBody requestBody = new MultipartBody.Builder()
final Request request = new Request.Builder().url(path).post(formBody).build();
//通過request的對象去構(gòu)造得到一個Call對象(類似于將請求封裝成了任務(wù))盈简,可調(diào)用execute()和cancel()等方法
Call call = mOkHttpClient.newCall(request);
//請求加入調(diào)度隊列,任務(wù)執(zhí)行完成在Callback中即可得到結(jié)果:調(diào)用call.enqueue以異步的方式去執(zhí)行請求(調(diào)用call.execute以同步阻塞的方式在主線程去執(zhí)行請求)
//注意:onFailure()和onResponse()是在異步線程里執(zhí)行的太示,所以如果把更新UI的操作寫在這兩個方法里會報錯柠贤,這個時候可以用runOnUiThread這個方法
call.enqueue(new Callback() {
@Override
//當(dāng)取消一個請求(調(diào)用cancel()),網(wǎng)絡(luò)連接錯誤类缤,或者超時都會回調(diào)
public void onFailure(Call call, IOException e) {
Log.v("Okhttp_onFailure",call.toString()+","+e.getMessage()+"");
/*mOkHttpClient.dispatcher().cancelAll();//使用Call.cancel()可以立即停止掉一個正在執(zhí)行的call*/
mOkHttpClient.connectionPool().evictAll();//清除并關(guān)閉連接池
try {
if(Okhttp.this.activity instanceof MainActivity){
MainActivity activity = (MainActivity) Okhttp.this.activity;
Message message = new Message();
if(e.getMessage().toString().contains("UnknownHostException")||e.getMessage().toString().contains("resolve")){//無法解析主機(jī)(1臼勉、IP越界)
message.what = UNKNOWN_HOST;
}else if(e.getMessage().toString().contains("SocketTimeoutException")||e.getMessage().toString().contains("after")){//連接超時(2、IP不越界且服務(wù)器已啟動)
message.what = SOCKET_TIMEOUT;
}else if(e.getMessage().toString().contains("ConnectException")||e.getMessage().toString().contains("Failed")){//服務(wù)器連接出錯(3餐弱、IP不越界且服務(wù)器未啟動)
message.what = CONNECT_EXCEPTION;
}else if(e.getMessage().toString().contains("closed")||e.getMessage().toString().contains("Canceled")) {//主動取消(測試未遇到到該情況)
message.what = CLOSED;
}else {
message.what = UNKNOWN_ERROR;//其他情況
}
activity.getHandler().sendMessage(message);
}else if(Okhttp.this.activity instanceof LoginActivity){
LoginActivity activity = (LoginActivity)Okhttp.this.activity;
Message message = new Message();
if(e.getMessage().toString().contains("UnknownHostException")||e.getMessage().toString().contains("resolve")){//無法解析主機(jī)(1宴霸、IP越界)
message.what = UNKNOWN_HOST;
}else if(e.getMessage().toString().contains("SocketTimeoutException")||e.getMessage().toString().contains("after")){//連接超時(2囱晴、IP不越界且服務(wù)器已啟動)
message.what = SOCKET_TIMEOUT;
}else if(e.getMessage().toString().contains("ConnectException")||e.getMessage().toString().contains("Failed")){//服務(wù)器連接出錯(3、IP不越界且服務(wù)器未啟動)
message.what = CONNECT_EXCEPTION;
}else if(e.getMessage().toString().contains("closed")||e.getMessage().toString().contains("Canceled")) {//主動取消
message.what = CLOSED;
}else {
message.what = UNKNOWN_ERROR;//其他情況
}
activity.getHandler().sendMessage(message);
}else {
Log.v("Okhttp_elseFailure",call.toString()+" "+e.getMessage()+"");
}
}catch (Exception e1){
e1.printStackTrace();
}
}
@Override
//請求成功時回調(diào)方法,response就是從服務(wù)器得到的參數(shù)
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
//response.body()函數(shù)獲得服務(wù)器返回的數(shù)據(jù)
// string()函數(shù)用來處理文本數(shù)據(jù)(傳遞文本數(shù)據(jù))瓢谢,bytes()函數(shù)用來處理字節(jié)數(shù)組(收到小型文件數(shù)據(jù)畸写,先以字節(jié)數(shù)據(jù)的形式保存在內(nèi)存中,然后再將其一次性寫入文件)氓扛,byteStream()函數(shù)用來處理字節(jié)流(下載文件較大時枯芬,通過流的形式,將數(shù)據(jù)保存在文件中)
//由于OkHttp封裝了okio采郎,所以可以將響應(yīng)數(shù)據(jù)通過BufferedSource的形式返回(斷點續(xù)傳功能),即response.body().source()
aa = response.body().string();
Log.v("Okhttp_response",call.toString()+" "+aa+"");
try{
httpRespone.onPostFinishedResponse(aa);
Gson gson = new Gson();
BB = gson.fromJson(aa,clazz);
httpRespone.onPostFinished(BB);
}catch (Exception e){
Log.v("Okhttp_onResponseErr",e.getMessage()+"");
}
}else {
Log.v("Okhttp_UnexpectedCode",response+"");
throw new IOException("Unexpected code " + response);
}
response.close();//無論任何情況都要關(guān)閉該對象
}
});
/*Log.v("Okhttp_call.equne",call.toString()+"");*/
return (T)BB;
}
public <T>T OkhttpPost(String path, HttpBuilder httpBuilder, final Type type, final HttpResponse httpRespone, final HttpRequestFail httpRequestFail){
//創(chuàng)建okHttpClient對象千所,OkHttpClient配置包括代理設(shè)置、超時設(shè)置(連接蒜埋、讀取和寫入超時)淫痰、緩存設(shè)置等
final OkHttpClient mOkHttpClient=mClinet
.newBuilder()
.readTimeout(5000,TimeUnit.MILLISECONDS)
.connectTimeout(5000,TimeUnit.MILLISECONDS)
.writeTimeout(5000,TimeUnit.MILLISECONDS)
/*.addInterceptor(new RetryInterceptor(1))*/
.build();
//創(chuàng)建一個Request:通過Request.Builder設(shè)置url(參數(shù)最起碼有個url)、method整份、header等參數(shù)
RequestBody formBody = httpBuilder.getBuilder().build();//MultipartBuilder可以構(gòu)建復(fù)雜的請求體,即RequestBody requestBody = new MultipartBody.Builder()
final Request request = new Request.Builder().url(path).post(formBody).build();
//通過request的對象去構(gòu)造得到一個Call對象(類似于將請求封裝成了任務(wù))黑界,可調(diào)用execute()和cancel()等方法
Call call = mOkHttpClient.newCall(request);
//請求加入調(diào)度隊列,任務(wù)執(zhí)行完成在Callback中即可得到結(jié)果:調(diào)用call.enqueue以異步的方式去執(zhí)行請求(調(diào)用call.execute以同步阻塞的方式在主線程去執(zhí)行請求)
//注意:onFailure()和onResponse()是在異步線程里執(zhí)行的皂林,所以如果把更新UI的操作寫在這兩個方法里會報錯朗鸠,這個時候可以用runOnUiThread這個方法
call.enqueue(new Callback() {
@Override
//當(dāng)取消一個請求(調(diào)用cancel()),網(wǎng)絡(luò)連接錯誤础倍,或者超時都會回調(diào)
public void onFailure(Call call, IOException e) {
Log.v("Okhttp_onFailure",call.toString()+","+e.getMessage()+"");
/*mOkHttpClient.dispatcher().cancelAll();//使用Call.cancel()可以立即停止掉一個正在執(zhí)行的call*/
mOkHttpClient.connectionPool().evictAll();//清除并關(guān)閉連接池
httpRequestFail.onRequestFail(e);
try {
if(Okhttp.this.activity instanceof LoginActivity){
LoginActivity activity = (LoginActivity)Okhttp.this.activity;
Message message = new Message();
if(e.getMessage().toString().contains("UnknownHostException")||e.getMessage().toString().contains("resolve")){//無法解析主機(jī)(1烛占、IP越界)
message.what = UNKNOWN_HOST;
}else if(e.getMessage().toString().contains("SocketTimeoutException")||e.getMessage().toString().contains("after")){//連接超時(2、IP不越界且服務(wù)器已啟動)
message.what = SOCKET_TIMEOUT;
}else if(e.getMessage().toString().contains("ConnectException")||e.getMessage().toString().contains("Failed")){//服務(wù)器連接出錯(3沟启、IP不越界且服務(wù)器未啟動)
message.what = CONNECT_EXCEPTION;
}else if(e.getMessage().toString().contains("closed")||e.getMessage().toString().contains("Canceled")) {//主動取消
message.what = CLOSED;
}else {
message.what = UNKNOWN_ERROR;//其他情況
}
activity.getHandler().sendMessage(message);
}else if(Okhttp.this.activity instanceof MainActivity){
MainActivity activity = (MainActivity) Okhttp.this.activity;
Message message = new Message();
if(e.getMessage().toString().contains("UnknownHostException")||e.getMessage().toString().contains("resolve")){//無法解析主機(jī)(1忆家、IP越界)
message.what = UNKNOWN_HOST;
}else if(e.getMessage().toString().contains("SocketTimeoutException")||e.getMessage().toString().contains("after")){//連接超時(2、IP不越界且服務(wù)器已啟動)
message.what = SOCKET_TIMEOUT;
}else if(e.getMessage().toString().contains("ConnectException")||e.getMessage().toString().contains("Failed")){//服務(wù)器連接出錯(3德迹、IP不越界且服務(wù)器未啟動)
message.what = CONNECT_EXCEPTION;
}else if(e.getMessage().toString().contains("closed")||e.getMessage().toString().contains("Canceled")) {//主動取消(測試未遇到到該情況)
message.what = CLOSED;
}else {
message.what = UNKNOWN_ERROR;//其他情況
}
activity.getHandler().sendMessage(message);
}else {
Log.v("Okhttp_elseFailure",call.toString()+" "+e.getMessage()+"");
}
}catch (Exception e1){
e1.printStackTrace();
}
}
@Override
//請求成功時回調(diào)方法,response就是從服務(wù)器得到的參數(shù)
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
//response.body()函數(shù)獲得服務(wù)器返回的數(shù)據(jù)
// string()函數(shù)用來處理文本數(shù)據(jù)(傳遞文本數(shù)據(jù))芽卿,bytes()函數(shù)用來處理字節(jié)數(shù)組(收到小型文件數(shù)據(jù),先以字節(jié)數(shù)據(jù)的形式保存在內(nèi)存中胳搞,然后再將其一次性寫入文件)卸例,byteStream()函數(shù)用來處理字節(jié)流(下載文件較大時,通過流的形式肌毅,將數(shù)據(jù)保存在文件中)
//由于OkHttp封裝了okio筷转,所以可以將響應(yīng)數(shù)據(jù)通過BufferedSource的形式返回(斷點續(xù)傳功能),即response.body().source()
aa = response.body().string();
Log.v("Okhttp_response",call.toString()+" "+aa+"");
try{
httpRespone.onPostFinishedResponse(aa);
Gson gson = new Gson();
BB = gson.fromJson(aa,type);
httpRespone.onPostFinished(BB);
}catch (Exception e){
Log.v("Okhttp_onResponseErr",e.getMessage()+"");
}
}else {
Log.v("Okhttp_UnexpectedCode",response+"");
throw new IOException("Unexpected code " + response);
}
response.close();//無論任何情況都要關(guān)閉該對象
}
});
/*Log.v("Okhttp_call.equne",call.toString()+"");*/
return (T)BB;
}
public interface HttpBuilder {
FormBody.Builder getBuilder();
}
public interface HttpResponse {
void onPostFinishedResponse(String response);
void onPostFinished(Object object);
}
public interface HttpRequestFail{
void onRequestFail(Exception e);
}
}
備注:
因為是從已有的項目中拉出來的代碼,可能有些資源文件沒有上傳悬而,一般問題不大呜舒。有疑問的可隨時留言,我會進(jìn)行答復(fù)和補(bǔ)充代碼笨奠。