├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── ACache.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── tsy
│ │ └── baseandroidproject
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── tsy
│ │ │ └── baseandroidproject
│ │ │ ├── Base
│ │ │ ├── BaseActivity.java
│ │ │ ├── BasePresenter.java
│ │ │ └── BaseView.java
│ │ │ ├── GlobalApp.java
│ │ │ └── feature
│ │ │ ├── Home
│ │ │ ├── contract
│ │ │ │ └── HomeContract.java
│ │ │ ├── interactor
│ │ │ │ └── HomeInteractor.java
│ │ │ ├── presenter
│ │ │ │ └── HomePresenter.java
│ │ │ └── view
│ │ │ │ └── HomeActivity.java
│ │ │ └── login
│ │ │ ├── bean
│ │ │ └── UserInfo.java
│ │ │ ├── contract
│ │ │ └── LoginContract.java
│ │ │ ├── interactor
│ │ │ └── LoginInteractor.java
│ │ │ ├── presenter
│ │ │ └── LoginPresenter.java
│ │ │ └── view
│ │ │ └── LoginActivity.java
│ └── res
│ │ ├── layout
│ │ ├── activity_home.xml
│ │ └── activity_login.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── tsy
│ └── baseandroidproject
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── myokhttp
├── .gitignore
├── README.md
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── tsy
│ │ └── sdk
│ │ └── myokhttp
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── tsy
│ │ │ └── sdk
│ │ │ └── myokhttp
│ │ │ ├── MyOkHttp.java
│ │ │ ├── body
│ │ │ ├── ProgressRequestBody.java
│ │ │ └── ResponseProgressBody.java
│ │ │ ├── response
│ │ │ ├── DownloadResponseHandler.java
│ │ │ ├── GsonResponseHandler.java
│ │ │ ├── IResponseHandler.java
│ │ │ ├── JsonResponseHandler.java
│ │ │ └── RawResponseHandler.java
│ │ │ └── util
│ │ │ └── LogUtils.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── tsy
│ └── sdk
│ └── myokhttp
│ └── ExampleUnitTest.java
├── myutil
├── .gitignore
├── README.md
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── tsy
│ │ └── sdk
│ │ └── myutil
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── tsy
│ │ │ └── sdk
│ │ │ └── myutil
│ │ │ ├── BitmapUtils.java
│ │ │ ├── DeviceUtils.java
│ │ │ ├── HttpURLConnectionUtils.java
│ │ │ ├── LogUtils.java
│ │ │ ├── MD5Utils.java
│ │ │ ├── ManifestUtils.java
│ │ │ ├── NetworkUtils.java
│ │ │ ├── StringUtils.java
│ │ │ └── ToastUtils.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── tsy
│ └── sdk
│ └── myutil
│ └── ExampleUnitTest.java
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BaseAndroidProject
2 | Android项目基础架构。包含架构分层、基本工具层等, 持续更新中
3 |
4 | ## 架构
5 |
6 | 1. 基于MVP架构进行分层.详见[http://www.jianshu.com/p/2ca7767df08c](http://www.jianshu.com/p/2ca7767df08c)
7 | 1. 规范命名.详见[http://www.jianshu.com/p/fcdded2f8444](http://www.jianshu.com/p/fcdded2f8444)
8 |
9 | ## 底层库
10 |
11 | ### 网络库
12 |
13 | 采用二次封装后的okhttp3+Gson.(没有使用retrofit,考虑到服务端提供的API可能不会很标准)
14 |
15 | 基本功能:
16 |
17 | 1. POST请求
18 | 1. GET请求
19 | 1. 上传文件&进度监听
20 | 1. 下载文件&进度监听
21 | 1. 返回可以选择Gson格式
22 | 1. 取消某个context的所有网络请求
23 |
24 | 并且将该功能模块独立为MyOkhttp,可以重复使用.
25 |
26 | 详细使用见:
27 |
28 | [MyOkhttp README](https://github.com/tsy12321/BaseAndroidProject/tree/master/myokhttp)
29 |
30 | ### 通用工具库
31 |
32 | 将常用的util封装到一个module - myutil
33 |
34 | 详细目录wiki见:
35 |
36 | [MyUtil README](https://github.com/tsy12321/BaseAndroidProject/tree/master/myutil)
37 |
38 | ### 依赖注入库
39 |
40 | ButterKnife.
41 |
42 | 详见[http://www.jianshu.com/p/32f6260ac300](http://www.jianshu.com/p/32f6260ac300)
43 |
44 | ### 图片开源库
45 |
46 | Glide.
47 |
48 | 详见[http://www.jianshu.com/p/18618ad47d01](http://www.jianshu.com/p/18618ad47d01)
49 |
50 | ### 缓存开源库
51 |
52 | ASimpleCache.
53 |
54 | 详见[http://www.jianshu.com/p/25c107ed7348](http://www.jianshu.com/p/25c107ed7348)
55 |
56 | ### Android M权限控制库
57 |
58 | Easypermissions
59 |
60 | 详见[http://www.jianshu.com/p/2b3661928e66](http://www.jianshu.com/p/2b3661928e66)
61 |
62 | ### 欢迎关注我的公众号
63 |
64 | 
65 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.tsy.baseandroidproject"
9 | minSdkVersion 9
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | buildscript {
23 | repositories {
24 | mavenCentral()
25 | }
26 | dependencies {
27 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
28 | }
29 | }
30 |
31 | apply plugin: 'com.neenbedankt.android-apt'
32 |
33 | dependencies {
34 | testCompile 'junit:junit:4.12'
35 | compile 'com.android.support:appcompat-v7:23.4.0'
36 |
37 | //ButterKnife
38 | compile 'com.jakewharton:butterknife:8.2.1'
39 | apt 'com.jakewharton:butterknife-compiler:8.2.1'
40 | //glide
41 | compile 'com.github.bumptech.glide:glide:3.7.0'
42 | //easypermission
43 | compile 'pub.devrel:easypermissions:0.1.9'
44 | //cache
45 | compile files('libs/ACache.jar')
46 | //okhttp
47 | compile project(':myokhttp')
48 | //myutil
49 | compile project(':myutil')
50 | }
51 |
--------------------------------------------------------------------------------
/app/libs/ACache.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/app/libs/ACache.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/tsy/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/tsy/baseandroidproject/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/Base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.Base;
2 |
3 | import android.app.Activity;
4 |
5 | /**
6 | * BaseActivity
7 | * Created by tsy on 16/7/22.
8 | */
9 | public class BaseActivity extends Activity {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/Base/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.Base;
2 |
3 |
4 | /**
5 | * Created by tsy on 16/7/26.
6 | */
7 | public interface BasePresenter {
8 | void start();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/Base/BaseView.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.Base;
2 |
3 | /**
4 | * Created by tsy on 16/8/30.
5 | */
6 | public interface BaseView {
7 | void showToast(String msg);
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/GlobalApp.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | /**
7 | * 全局Application
8 | * Created by tsy on 16/7/15.
9 | */
10 | public class GlobalApp extends Application {
11 |
12 | private static GlobalApp mGlobalApp;
13 | private Context mContext;
14 |
15 | @Override
16 | public void onCreate() {
17 | super.onCreate();
18 |
19 | mGlobalApp = this;
20 | this.mContext = getApplicationContext();
21 | }
22 |
23 | /**
24 | * 获取全局Application
25 | * @return
26 | */
27 | public static synchronized GlobalApp getInstance() {
28 | return mGlobalApp;
29 | }
30 |
31 | /**
32 | * 获取ApplicationContext
33 | * @return
34 | */
35 | public Context getContext() {
36 | return mContext;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/Home/contract/HomeContract.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.Home.contract;
2 |
3 | import com.tsy.baseandroidproject.Base.BasePresenter;
4 | import com.tsy.baseandroidproject.Base.BaseView;
5 |
6 | /**
7 | * Created by tsy on 16/8/30.
8 | */
9 | public interface HomeContract {
10 |
11 | interface View extends BaseView {
12 |
13 | }
14 |
15 | interface Presenter extends BasePresenter {
16 | void onPost();
17 | }
18 |
19 | interface Interactor {
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/Home/interactor/HomeInteractor.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.Home.interactor;
2 |
3 | import com.tsy.baseandroidproject.feature.Home.contract.HomeContract;
4 |
5 | /**
6 | * Created by tsy on 16/8/30.
7 | */
8 | public class HomeInteractor implements HomeContract.Interactor {
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/Home/presenter/HomePresenter.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.Home.presenter;
2 |
3 | import com.tsy.baseandroidproject.feature.Home.contract.HomeContract;
4 | import com.tsy.baseandroidproject.feature.Home.interactor.HomeInteractor;
5 | import com.tsy.baseandroidproject.feature.login.contract.LoginContract;
6 | import com.tsy.baseandroidproject.feature.login.interactor.LoginInteractor;
7 |
8 | /**
9 | * Created by tsy on 16/8/30.
10 | */
11 | public class HomePresenter implements HomeContract.Presenter {
12 |
13 | private HomeContract.View mView;
14 | private HomeContract.Interactor mInteractor;
15 | private LoginContract.Interactor mLoginInteractor;
16 |
17 | public HomePresenter(HomeContract.View view) {
18 | mView = view;
19 | mInteractor = new HomeInteractor();
20 | mLoginInteractor = new LoginInteractor();
21 | }
22 |
23 | @Override
24 | public void start() {
25 |
26 | }
27 |
28 | @Override
29 | public void onPost() {
30 | //判断用户有没有登录
31 | if(!mLoginInteractor.isLogin()) {
32 | // 跳转登录
33 | // TODO: 16/8/30
34 | return;
35 | }
36 |
37 | //跳转发帖页面
38 | // TODO: 16/8/30
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/Home/view/HomeActivity.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.Home.view;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.tsy.baseandroidproject.Base.BaseActivity;
6 | import com.tsy.baseandroidproject.R;
7 | import com.tsy.baseandroidproject.feature.Home.contract.HomeContract;
8 | import com.tsy.baseandroidproject.feature.Home.presenter.HomePresenter;
9 |
10 | import butterknife.ButterKnife;
11 | import butterknife.OnClick;
12 |
13 | public class HomeActivity extends BaseActivity implements HomeContract.View {
14 |
15 | private HomeContract.Presenter mPresnter;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_home);
21 | ButterKnife.bind(this);
22 |
23 | mPresnter = new HomePresenter(this);
24 | }
25 |
26 | @OnClick(R.id.btnPost)
27 | public void onPost() {
28 | mPresnter.onPost();
29 | }
30 |
31 | @Override
32 | public void showToast(String msg) {
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/login/bean/UserInfo.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.login.bean;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by tsy on 16/8/30.
7 | */
8 | public class UserInfo implements Serializable {
9 |
10 | private static final long serialVersionUID = 1L; // 定义序列化ID
11 |
12 | public String uid;
13 | public String userName;
14 | public String token;
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/login/contract/LoginContract.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.login.contract;
2 |
3 | import com.tsy.baseandroidproject.Base.BasePresenter;
4 | import com.tsy.baseandroidproject.Base.BaseView;
5 | import com.tsy.baseandroidproject.feature.login.bean.UserInfo;
6 |
7 | /**
8 | * Login接口层
9 | * Created by tsy on 16/8/30.
10 | */
11 | public interface LoginContract {
12 |
13 | interface View extends BaseView {
14 | /**
15 | * 跳转Home
16 | */
17 | void goHome();
18 | }
19 |
20 | interface Presenter extends BasePresenter {
21 | /**
22 | * login
23 | * @param phone
24 | * @param password
25 | */
26 | void onLogin(String phone, String password);
27 | }
28 |
29 | interface Interactor {
30 | /**
31 | * do login
32 | * @param phone
33 | * @param password
34 | * @param callback
35 | */
36 | void doLogin(String phone, String password, LoginCallback callback);
37 | interface LoginCallback {
38 | void onSuccess(UserInfo user_info);
39 | void onFailure(String msg);
40 | }
41 |
42 | /**
43 | * 是否登录
44 | * @return
45 | */
46 | boolean isLogin();
47 |
48 | /**
49 | * 获取当前登录用户
50 | * @return
51 | */
52 | UserInfo getLoginUser();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/login/interactor/LoginInteractor.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.login.interactor;
2 |
3 | import android.os.Handler;
4 |
5 | import com.tsy.baseandroidproject.GlobalApp;
6 | import com.tsy.baseandroidproject.feature.login.bean.UserInfo;
7 | import com.tsy.baseandroidproject.feature.login.contract.LoginContract;
8 | import com.tsy.sdk.acache.ACache;
9 | import com.tsy.sdk.myokhttp.MyOkHttp;
10 | import com.tsy.sdk.myutil.StringUtils;
11 |
12 | /**
13 | * Login Interactor层
14 | * Created by tsy on 16/8/30.
15 | */
16 | public class LoginInteractor implements LoginContract.Interactor {
17 |
18 | private MyOkHttp mApi;
19 | private ACache mCache;
20 |
21 | //缓存key
22 | private final String CACHE_KEY_USERINFO = "CACHE_KEY_USERINFO";
23 |
24 | public LoginInteractor() {
25 | mApi = MyOkHttp.get();
26 | mCache = ACache.get(GlobalApp.getInstance().getContext());
27 | }
28 |
29 | @Override
30 | public void doLogin(String phone, String password, final LoginCallback callback) {
31 | //模拟异步网络请求登录
32 |
33 | Handler handler = new Handler();
34 |
35 | handler.postDelayed(new Runnable() {
36 | @Override
37 | public void run() {
38 | UserInfo userInfo = new UserInfo();
39 | userInfo.uid = "1212121";
40 | userInfo.userName = "tsy12321";
41 | userInfo.token = "wqw13w12312wsqw12";
42 |
43 | //存入缓存
44 | mCache.put(CACHE_KEY_USERINFO, userInfo);
45 |
46 | callback.onSuccess(userInfo);
47 | }
48 | }, 2000);
49 | }
50 |
51 | @Override
52 | public boolean isLogin() {
53 | UserInfo userInfo = (UserInfo) mCache.getAsObject(CACHE_KEY_USERINFO);
54 | if(!StringUtils.isEmpty(userInfo.uid) && !StringUtils.isEmpty(userInfo.token)) {
55 | return true;
56 | }
57 | return false;
58 | }
59 |
60 | @Override
61 | public UserInfo getLoginUser() {
62 | return (UserInfo) mCache.getAsObject(CACHE_KEY_USERINFO);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/login/presenter/LoginPresenter.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.login.presenter;
2 |
3 | import com.tsy.baseandroidproject.feature.login.bean.UserInfo;
4 | import com.tsy.baseandroidproject.feature.login.contract.LoginContract;
5 | import com.tsy.baseandroidproject.feature.login.interactor.LoginInteractor;
6 | import com.tsy.sdk.myutil.StringUtils;
7 |
8 | /**
9 | * Login presenter层
10 | * Created by tsy on 16/8/30.
11 | */
12 | public class LoginPresenter implements LoginContract.Presenter {
13 |
14 | private LoginContract.View mView;
15 | private LoginContract.Interactor mInteractor;
16 |
17 | public LoginPresenter(LoginContract.View view) {
18 | mView = view;
19 | mInteractor = new LoginInteractor();
20 | }
21 |
22 | @Override
23 | public void start() {
24 |
25 | }
26 |
27 | @Override
28 | public void onLogin(String phone, String password) {
29 | if(StringUtils.isEmpty(phone)) {
30 | mView.showToast("Empty phone");
31 | return;
32 | }
33 |
34 | if(StringUtils.isEmpty(password)) {
35 | mView.showToast("Empty password");
36 | return;
37 | }
38 |
39 | mInteractor.doLogin(phone, password, new LoginContract.Interactor.LoginCallback() {
40 | @Override
41 | public void onSuccess(UserInfo user_info) {
42 | mView.goHome();
43 | }
44 |
45 | @Override
46 | public void onFailure(String msg) {
47 | mView.showToast(msg);
48 | }
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tsy/baseandroidproject/feature/login/view/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject.feature.login.view;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.widget.EditText;
6 |
7 | import com.tsy.baseandroidproject.Base.BaseActivity;
8 | import com.tsy.baseandroidproject.GlobalApp;
9 | import com.tsy.baseandroidproject.R;
10 | import com.tsy.baseandroidproject.feature.Home.view.HomeActivity;
11 | import com.tsy.baseandroidproject.feature.login.contract.LoginContract;
12 | import com.tsy.baseandroidproject.feature.login.presenter.LoginPresenter;
13 | import com.tsy.sdk.myutil.ToastUtils;
14 |
15 | import butterknife.BindView;
16 | import butterknife.ButterKnife;
17 | import butterknife.OnClick;
18 |
19 | public class LoginActivity extends BaseActivity implements LoginContract.View {
20 |
21 | @BindView(R.id.editPhone)
22 | EditText editPhone;
23 |
24 | @BindView(R.id.editPassword)
25 | EditText editPassword;
26 |
27 | private LoginContract.Presenter mPresenter;
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | setContentView(R.layout.activity_login);
33 | ButterKnife.bind(this);
34 |
35 | mPresenter = new LoginPresenter(this);
36 | }
37 |
38 | @OnClick(R.id.btnLogin)
39 | public void onLogin() {
40 | mPresenter.onLogin(editPhone.getText().toString(), editPassword.getText().toString());
41 | }
42 |
43 | @OnClick(R.id.txtRegister)
44 | public void goRegister() {
45 | ToastUtils.showShort(GlobalApp.getInstance().getContext(), "goRegister");
46 | }
47 |
48 | @OnClick(R.id.txtForgetPwd)
49 | public void goForgetPwd() {
50 | ToastUtils.showShort(GlobalApp.getInstance().getContext(), "goForgetPwd");
51 | }
52 |
53 | @Override
54 | public void showToast(String msg) {
55 | ToastUtils.showShort(GlobalApp.getInstance().getContext(), msg);
56 | }
57 |
58 | @Override
59 | public void goHome() {
60 | //跳转Home页面
61 | ToastUtils.showShort(GlobalApp.getInstance().getContext(), "登录成功, 跳转Home页面");
62 |
63 | Intent intent = new Intent(this, HomeActivity.class);
64 | startActivity(intent);
65 | finish();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
20 |
21 |
22 |
25 |
30 |
36 |
37 |
41 |
42 |
54 |
55 |
56 |
61 |
62 |
66 |
67 |
78 |
79 |
80 |
81 |
90 |
91 |
97 |
98 |
104 |
105 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BaseAndroidProject
3 | Sign in
4 |
5 |
6 | Email
7 | Password (optional)
8 | Sign in or register
9 | Sign in
10 | This email address is invalid
11 | This password is too short
12 | This password is incorrect
13 | This field is required
14 | "Contacts permissions are needed for providing email
15 | completions."
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/tsy/baseandroidproject/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.tsy.baseandroidproject;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tsy12321/BaseAndroidProject/ad8d5762f814006215dc075551e18d47547b5832/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/myokhttp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/myokhttp/README.md:
--------------------------------------------------------------------------------
1 | ## MyOkhttp Wiki
2 |
3 | > 该模块对Okhttp3进行二次封装,对外提供了POST请求,GET请求,上传文件,下载文件,取消请求和Gson转换等功能.
4 |
5 | ### 0 版本更新
6 |
7 | |日期|更新内容|
8 | |---|---|
9 | |2016-08-17|完成POST请求,GET请求,上传文件,下载文件,取消请求和Gson转换功能|
10 | |2016-08-18|结果回调增加RawResponseHandler-直接返回字符串|
11 | |2016-08-30|调用请求增加无context参数的重载方法|
12 |
13 | ### 1 POST请求
14 |
15 | ```java
16 | Map params = new HashMap();
17 | params.put("name", "tsy");
18 |
19 | MyOkHttp.get().post(this, "http://192.168.3.1/test_okhttp.php", params, new JsonResponseHandler() {
20 | @Override
21 | public void onSuccess(int statusCode, JSONObject response) {
22 | LogUtils.v(TAG, statusCode + " " + response);
23 | }
24 |
25 | @Override
26 | public void onFailure(int statusCode, String error_msg) {
27 | LogUtils.v(TAG, statusCode + " " + error_msg);
28 | }
29 | });
30 | ```
31 |
32 | ### 2 GET请求
33 |
34 | ```java
35 | Map params = new HashMap();
36 | params.put("name", "tsy");
37 |
38 | MyOkHttp.get().get(this, "http://192.168.3.1/test_okhttp.php", params, new RawResponseHandler() {
39 | @Override
40 | public void onSuccess(int statusCode, String response) {
41 | LogUtils.v(TAG, statusCode + " " + response);
42 | }
43 |
44 | @Override
45 | public void onFailure(int statusCode, String error_msg) {
46 | LogUtils.v(TAG, statusCode + " " + error_msg);
47 | }
48 | });
49 | ```
50 |
51 | ### 3 上传文件
52 |
53 | ```java
54 | Map params = new HashMap();
55 | params.put("name", "tsy");
56 |
57 | Map files = new HashMap();
58 | File file = new File(Environment.getExternalStorageDirectory() + "/com.ci123.service.splashandroid/splash/1.png");
59 | files.put("avatar", file);
60 |
61 | MyOkHttp.get().upload(this, "http://192.168.3.1/test_post.php", params, files, new GsonResponseHandler() {
62 | @Override
63 | public void onFailure(int statusCode, String error_msg) {
64 | LogUtils.v(TAG, statusCode + " " + error_msg);
65 | }
66 |
67 | @Override
68 | public void onSuccess(int statusCode, BB response) {
69 | LogUtils.v(TAG, statusCode + " " + response.ret);
70 | }
71 |
72 | @Override
73 | public void onProgress(long currentBytes, long totalBytes) {
74 | LogUtils.v(TAG, currentBytes + "/" + totalBytes);
75 | }
76 | });
77 | ```
78 |
79 | ### 4 下载文件
80 |
81 | ```java
82 | MyOkHttp.get().download(this, "http://192.168.3.1/output_tmp.jpg",
83 | Environment.getExternalStorageDirectory() + "/com.tsy.splashandroid/", "1.jpg",
84 | new DownloadResponseHandler() {
85 | @Override
86 | public void onFinish(File download_file) {
87 | LogUtils.v(TAG, "onFinish:" + download_file.getPath());
88 | }
89 |
90 | @Override
91 | public void onProgress(long currentBytes, long totalBytes) {
92 | LogUtils.v(TAG, currentBytes + "/" + totalBytes);
93 | }
94 |
95 | @Override
96 | public void onFailure(String error_msg) {
97 | LogUtils.v(TAG, error_msg);
98 | }
99 | });
100 | ```
101 |
102 | ### 5 取消请求(建议放在BaseActivity,BaseFragment的onDestroy中)
103 |
104 | ```java
105 | MyOkHttp.get().cancel(this);
106 | ```
107 |
108 | ### 6 返回格式
109 |
110 | post,get,upload3个接口可以选择返回格式为普通Json还是Gson
111 |
112 | #### 6.1 普通json
113 |
114 | 回调继承JsonResponseHandler,例如POST请求的例子
115 |
116 | #### 6.2 gson
117 |
118 | 回调继承GsonResponseHandler,并设置泛型T,例如Upload请求的例子
119 |
120 | #### 6.3 raw原始数据
121 |
122 | 回调继承RawResponseHandler,例如GET请求例子
123 |
124 | ### 7 tag
125 |
126 | 每个接口都有一个不带首个Context参数的重载函数:
127 |
128 | ```java
129 | Map params = new HashMap();
130 | params.put("name", "tsy");
131 |
132 | MyOkHttp.get().post(this, "http://192.168.3.1/test_okhttp.php", params, new JsonResponseHandler() {
133 | @Override
134 | public void onSuccess(int statusCode, JSONObject response) {
135 | LogUtils.v(TAG, statusCode + " " + response);
136 | }
137 |
138 | @Override
139 | public void onFailure(int statusCode, String error_msg) {
140 | LogUtils.v(TAG, statusCode + " " + error_msg);
141 | }
142 | });
143 | ```
144 |
145 | ```java
146 | Map params = new HashMap();
147 | params.put("name", "tsy");
148 |
149 | MyOkHttp.get().post("http://192.168.3.1/test_okhttp.php", params, new JsonResponseHandler() {
150 | @Override
151 | public void onSuccess(int statusCode, JSONObject response) {
152 | LogUtils.v(TAG, statusCode + " " + response);
153 | }
154 |
155 | @Override
156 | public void onFailure(int statusCode, String error_msg) {
157 | LogUtils.v(TAG, statusCode + " " + error_msg);
158 | }
159 | });
160 | ```
161 |
162 | **如果不是在activity等中发起的请求可以使用后一个方法.前一个方法适用于在activity等中发起的请求,并在activity销毁的时候统一取消.**
--------------------------------------------------------------------------------
/myokhttp/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 9
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | testCompile 'junit:junit:4.12'
24 | compile 'com.android.support:appcompat-v7:23.4.0'
25 |
26 | compile 'com.squareup.okhttp3:okhttp:3.4.1'
27 | compile 'com.google.code.gson:gson:2.7'
28 | compile 'com.squareup.okio:okio:1.9.0'
29 | }
30 |
--------------------------------------------------------------------------------
/myokhttp/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/tsy/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/myokhttp/src/androidTest/java/com/tsy/sdk/myokhttp/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/myokhttp/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/MyOkHttp.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp;
2 |
3 | import android.content.Context;
4 | import android.os.Handler;
5 |
6 | import com.google.gson.Gson;
7 | import com.tsy.sdk.myokhttp.body.ProgressRequestBody;
8 | import com.tsy.sdk.myokhttp.body.ResponseProgressBody;
9 | import com.tsy.sdk.myokhttp.response.DownloadResponseHandler;
10 | import com.tsy.sdk.myokhttp.response.GsonResponseHandler;
11 | import com.tsy.sdk.myokhttp.response.IResponseHandler;
12 | import com.tsy.sdk.myokhttp.response.JsonResponseHandler;
13 | import com.tsy.sdk.myokhttp.response.RawResponseHandler;
14 | import com.tsy.sdk.myokhttp.util.LogUtils;
15 |
16 | import org.json.JSONException;
17 | import org.json.JSONObject;
18 |
19 | import java.io.File;
20 | import java.io.FileOutputStream;
21 | import java.io.IOException;
22 | import java.io.InputStream;
23 | import java.net.FileNameMap;
24 | import java.net.URLConnection;
25 | import java.util.Map;
26 |
27 | import okhttp3.Call;
28 | import okhttp3.Callback;
29 | import okhttp3.FormBody;
30 | import okhttp3.Headers;
31 | import okhttp3.Interceptor;
32 | import okhttp3.MediaType;
33 | import okhttp3.MultipartBody;
34 | import okhttp3.OkHttpClient;
35 | import okhttp3.Request;
36 | import okhttp3.RequestBody;
37 | import okhttp3.Response;
38 |
39 | /**
40 | * 封装好的MyOkhttp
41 | * Created by tsy on 16/8/15.
42 | */
43 | public class MyOkHttp {
44 |
45 | private OkHttpClient client;
46 | private static MyOkHttp instance;
47 |
48 | public MyOkHttp() {
49 | client = new OkHttpClient();
50 | }
51 |
52 | /**
53 | * 获取句柄
54 | * @return
55 | */
56 | public static MyOkHttp get() {
57 | if(instance == null) {
58 | instance = new MyOkHttp();
59 | }
60 |
61 | return instance;
62 | }
63 |
64 | /**
65 | * post 请求
66 | * @param url url
67 | * @param params 参数
68 | * @param responseHandler 回调
69 | */
70 | public void post(final String url, final Map params, final IResponseHandler responseHandler) {
71 | post(null, url, params, responseHandler);
72 | }
73 |
74 | /**
75 | * post 请求
76 | * @param context 发起请求的context
77 | * @param url url
78 | * @param params 参数
79 | * @param responseHandler 回调
80 | */
81 | public void post(Context context, final String url, final Map params, final IResponseHandler responseHandler) {
82 | //post builder 参数
83 | FormBody.Builder builder = new FormBody.Builder();
84 | if(params != null && params.size() > 0) {
85 | for (Map.Entry entry : params.entrySet()) {
86 | builder.add(entry.getKey(), entry.getValue());
87 | }
88 | }
89 |
90 | Request request;
91 |
92 | //发起request
93 | if(context == null) {
94 | request = new Request.Builder()
95 | .url(url)
96 | .post(builder.build())
97 | .build();
98 | } else {
99 | request = new Request.Builder()
100 | .url(url)
101 | .post(builder.build())
102 | .tag(context)
103 | .build();
104 | }
105 |
106 |
107 | client.newCall(request).enqueue(new MyCallback(new Handler(), responseHandler));
108 | }
109 |
110 | /**
111 | * get 请求
112 | * @param url url
113 | * @param params 参数
114 | * @param responseHandler 回调
115 | */
116 | public void get(final String url, final Map params, final IResponseHandler responseHandler) {
117 | get(null, url, params, responseHandler);
118 | }
119 |
120 | /**
121 | * get 请求
122 | * @param context 发起请求的context
123 | * @param url url
124 | * @param params 参数
125 | * @param responseHandler 回调
126 | */
127 | public void get(Context context, final String url, final Map params, final IResponseHandler responseHandler) {
128 | //拼接url
129 | String get_url = url;
130 | if(params != null && params.size() > 0) {
131 | int i = 0;
132 | for (Map.Entry entry : params.entrySet()) {
133 | if(i++ == 0) {
134 | get_url = get_url + "?" + entry.getKey() + "=" + entry.getValue();
135 | } else {
136 | get_url = get_url + "&" + entry.getKey() + "=" + entry.getValue();
137 | }
138 | }
139 | }
140 |
141 | Request request;
142 |
143 | //发起request
144 | if(context == null) {
145 | request = new Request.Builder()
146 | .url(url)
147 | .build();
148 | } else {
149 | request = new Request.Builder()
150 | .url(url)
151 | .tag(context)
152 | .build();
153 | }
154 |
155 | client.newCall(request).enqueue(new MyCallback(new Handler(), responseHandler));
156 | }
157 |
158 | /**
159 | * 上传文件
160 | * @param url url
161 | * @param files 上传的文件files
162 | * @param responseHandler 回调
163 | */
164 | public void upload(String url, Map files, final IResponseHandler responseHandler) {
165 | upload(null, url, null, files, responseHandler);
166 | }
167 |
168 | /**
169 | * 上传文件
170 | * @param url url
171 | * @param params 参数
172 | * @param files 上传的文件files
173 | * @param responseHandler 回调
174 | */
175 | public void upload(String url, Map params, Map files, final IResponseHandler responseHandler) {
176 | upload(null, url, params, files, responseHandler);
177 | }
178 |
179 | /**
180 | * 上传文件
181 | * @param context 发起请求的context
182 | * @param url url
183 | * @param files 上传的文件files
184 | * @param responseHandler 回调
185 | */
186 | public void upload(Context context, String url, Map files, final IResponseHandler responseHandler) {
187 | upload(context, url, null, files, responseHandler);
188 | }
189 |
190 | /**
191 | * 上传文件
192 | * @param context 发起请求的context
193 | * @param url url
194 | * @param params 参数
195 | * @param files 上传的文件files
196 | * @param responseHandler 回调
197 | */
198 | public void upload(Context context, String url, Map params, Map files, final IResponseHandler responseHandler) {
199 | MultipartBody.Builder multipartBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
200 |
201 | //添加参数
202 | if (params != null && !params.isEmpty()) {
203 | for (String key : params.keySet()) {
204 | multipartBuilder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + key + "\""),
205 | RequestBody.create(null, params.get(key)));
206 | }
207 | }
208 |
209 | //添加上传文件
210 | if (files != null && !files.isEmpty()) {
211 | RequestBody fileBody;
212 | for (String key : files.keySet()) {
213 | File file = files.get(key);
214 | String fileName = file.getName();
215 | fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file);
216 | multipartBuilder.addPart(Headers.of("Content-Disposition",
217 | "form-data; name=\"" + key + "\"; filename=\"" + fileName + "\""),
218 | fileBody);
219 | }
220 | }
221 |
222 | Request request;
223 | if(context == null) {
224 | request = new Request.Builder()
225 | .url(url)
226 | .post(new ProgressRequestBody(multipartBuilder.build(),responseHandler))
227 | .build();
228 | } else {
229 | request = new Request.Builder()
230 | .url(url)
231 | .post(new ProgressRequestBody(multipartBuilder.build(),responseHandler))
232 | .tag(context)
233 | .build();
234 | }
235 |
236 | client.newCall(request).enqueue(new MyCallback(new Handler(), responseHandler));
237 | }
238 |
239 | /**
240 | * 下载文件
241 | * @param url 下载地址
242 | * @param filedir 下载目的目录
243 | * @param filename 下载目的文件名
244 | * @param downloadResponseHandler 下载回调
245 | */
246 | public void download(String url, String filedir, String filename, final DownloadResponseHandler downloadResponseHandler) {
247 | download(null, url, filedir, filename, downloadResponseHandler);
248 | }
249 |
250 | /**
251 | * 下载文件
252 | * @param context 发起请求的context
253 | * @param url 下载地址
254 | * @param filedir 下载目的目录
255 | * @param filename 下载目的文件名
256 | * @param downloadResponseHandler 下载回调
257 | */
258 | public void download(Context context, String url, String filedir, String filename, final DownloadResponseHandler downloadResponseHandler) {
259 |
260 | Request request;
261 | if(context == null) {
262 | request = new Request.Builder()
263 | .url(url)
264 | .build();
265 | } else {
266 | request = new Request.Builder()
267 | .url(url)
268 | .tag(context)
269 | .build();
270 | }
271 |
272 | client.newBuilder()
273 | .addNetworkInterceptor(new Interceptor() { //设置拦截器
274 | @Override
275 | public Response intercept(Chain chain) throws IOException {
276 | Response originalResponse = chain.proceed(chain.request());
277 | return originalResponse.newBuilder()
278 | .body(new ResponseProgressBody(originalResponse.body(), downloadResponseHandler))
279 | .build();
280 | }
281 | })
282 | .build()
283 | .newCall(request)
284 | .enqueue(new MyDownloadCallback(new Handler(), downloadResponseHandler, filedir, filename));
285 | }
286 |
287 | /**
288 | * 取消当前context的所有请求
289 | * @param context
290 | */
291 | public void cancel(Context context) {
292 | if(client != null) {
293 | for(Call call : client.dispatcher().queuedCalls()) {
294 | if(call.request().tag().equals(context))
295 | call.cancel();
296 | }
297 | for(Call call : client.dispatcher().runningCalls()) {
298 | if(call.request().tag().equals(context))
299 | call.cancel();
300 | }
301 | }
302 | }
303 |
304 | //下载回调
305 | private class MyDownloadCallback implements Callback {
306 |
307 | private Handler mHandler;
308 | private DownloadResponseHandler mDownloadResponseHandler;
309 | private String mFileDir;
310 | private String mFilename;
311 |
312 | public MyDownloadCallback(Handler handler, DownloadResponseHandler downloadResponseHandler,
313 | String filedir, String filename) {
314 | mHandler = handler;
315 | mDownloadResponseHandler = downloadResponseHandler;
316 | mFileDir = filedir;
317 | mFilename = filename;
318 | }
319 |
320 | @Override
321 | public void onFailure(Call call, final IOException e) {
322 | LogUtils.e("onFailure", e);
323 |
324 | mHandler.post(new Runnable() {
325 | @Override
326 | public void run() {
327 | mDownloadResponseHandler.onFailure(e.toString());
328 | }
329 | });
330 | }
331 |
332 | @Override
333 | public void onResponse(Call call, final Response response) throws IOException {
334 | if(response.isSuccessful()) {
335 | File file = null;
336 | try {
337 | file = saveFile(response, mFileDir, mFilename);
338 | } catch (final IOException e) {
339 | LogUtils.e("onResponse saveFile fail", e);
340 |
341 | mHandler.post(new Runnable() {
342 | @Override
343 | public void run() {
344 | mDownloadResponseHandler.onFailure("onResponse saveFile fail." + e.toString());
345 | }
346 | });
347 | }
348 |
349 | final File newFile = file;
350 | mHandler.post(new Runnable() {
351 | @Override
352 | public void run() {
353 | mDownloadResponseHandler.onFinish(newFile);
354 | }
355 | });
356 | } else {
357 | LogUtils.e("onResponse fail status=" + response.code());
358 |
359 | mHandler.post(new Runnable() {
360 | @Override
361 | public void run() {
362 | mDownloadResponseHandler.onFailure("fail status=" + response.code());
363 | }
364 | });
365 | }
366 | }
367 | }
368 |
369 | //callback
370 | private class MyCallback implements Callback {
371 |
372 | private Handler mHandler;
373 | private IResponseHandler mResponseHandler;
374 |
375 | public MyCallback(Handler handler, IResponseHandler responseHandler) {
376 | mHandler = handler;
377 | mResponseHandler = responseHandler;
378 | }
379 |
380 | @Override
381 | public void onFailure(Call call, final IOException e) {
382 | LogUtils.e("onFailure", e);
383 |
384 | mHandler.post(new Runnable() {
385 | @Override
386 | public void run() {
387 | mResponseHandler.onFailure(0, e.toString());
388 | }
389 | });
390 | }
391 |
392 | @Override
393 | public void onResponse(Call call, final Response response) throws IOException {
394 | if(response.isSuccessful()) {
395 | final String response_body = response.body().string();
396 |
397 | if(mResponseHandler instanceof JsonResponseHandler) { //json回调
398 | try {
399 | final JSONObject jsonBody = new JSONObject(response_body);
400 | mHandler.post(new Runnable() {
401 | @Override
402 | public void run() {
403 | ((JsonResponseHandler)mResponseHandler).onSuccess(response.code(), jsonBody);
404 | }
405 | });
406 | } catch (JSONException e) {
407 | LogUtils.e("onResponse fail parse jsonobject, body=" + response_body);
408 | mHandler.post(new Runnable() {
409 | @Override
410 | public void run() {
411 | mResponseHandler.onFailure(response.code(), "fail parse jsonobject, body=" + response_body);
412 | }
413 | });
414 | }
415 | } else if(mResponseHandler instanceof GsonResponseHandler) { //gson回调
416 | mHandler.post(new Runnable() {
417 | @Override
418 | public void run() {
419 | try {
420 | Gson gson = new Gson();
421 | ((GsonResponseHandler)mResponseHandler).onSuccess(response.code(),
422 | gson.fromJson(response_body, ((GsonResponseHandler)mResponseHandler).getType()));
423 | } catch (Exception e) {
424 | LogUtils.e("onResponse fail parse gson, body=" + response_body, e);
425 | mResponseHandler.onFailure(response.code(), "fail parse gson, body=" + response_body);
426 | }
427 |
428 | }
429 | });
430 | } else if(mResponseHandler instanceof RawResponseHandler) { //raw字符串回调
431 | mHandler.post(new Runnable() {
432 | @Override
433 | public void run() {
434 | ((RawResponseHandler)mResponseHandler).onSuccess(response.code(), response_body);
435 | }
436 | });
437 | }
438 | } else {
439 | LogUtils.e("onResponse fail status=" + response.code());
440 |
441 | mHandler.post(new Runnable() {
442 | @Override
443 | public void run() {
444 | mResponseHandler.onFailure(0, "fail status=" + response.code());
445 | }
446 | });
447 | }
448 | }
449 | }
450 |
451 | //保存文件
452 | private File saveFile(Response response, String filedir, String filename) throws IOException {
453 | InputStream is = null;
454 | byte[] buf = new byte[2048];
455 | int len;
456 | FileOutputStream fos = null;
457 | try {
458 | is = response.body().byteStream();
459 | File dir = new File(filedir);
460 | if (!dir.exists()) {
461 | dir.mkdirs();
462 | }
463 | File file = new File(dir, filename);
464 | fos = new FileOutputStream(file);
465 | while ((len = is.read(buf)) != -1) {
466 | fos.write(buf, 0, len);
467 | }
468 | fos.flush();
469 | return file;
470 | } finally {
471 | try {
472 | if (is != null) is.close();
473 | } catch (IOException e) {
474 | }
475 | try {
476 | if (fos != null) fos.close();
477 | } catch (IOException e) {
478 | }
479 | }
480 | }
481 |
482 | //获取mime type
483 | private String guessMimeType(String path) {
484 | FileNameMap fileNameMap = URLConnection.getFileNameMap();
485 | String contentTypeFor = fileNameMap.getContentTypeFor(path);
486 | if (contentTypeFor == null) {
487 | contentTypeFor = "application/octet-stream";
488 | }
489 | return contentTypeFor;
490 | }
491 | }
492 |
493 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/body/ProgressRequestBody.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.body;
2 |
3 | import com.tsy.sdk.myokhttp.response.IResponseHandler;
4 |
5 | import java.io.IOException;
6 |
7 | import okhttp3.MediaType;
8 | import okhttp3.RequestBody;
9 | import okio.Buffer;
10 | import okio.BufferedSink;
11 | import okio.ForwardingSink;
12 | import okio.Okio;
13 | import okio.Sink;
14 |
15 | /**
16 | * 重写request body 设置上传进度监听
17 | * Created by tsy on 16/8/16.
18 | */
19 | public class ProgressRequestBody extends RequestBody {
20 |
21 | private IResponseHandler mResponseHandler; //回调监听
22 | private RequestBody mRequestBody;
23 | private BufferedSink mBufferedSink;
24 |
25 | public ProgressRequestBody(RequestBody requestBody, IResponseHandler responseHandler) {
26 | this.mResponseHandler = responseHandler;
27 | this.mRequestBody = requestBody;
28 | }
29 |
30 | @Override
31 | public MediaType contentType() {
32 | return mRequestBody.contentType();
33 | }
34 |
35 | @Override
36 | public long contentLength() throws IOException {
37 | return mRequestBody.contentLength();
38 | }
39 |
40 | @Override
41 | public void writeTo(BufferedSink sink) throws IOException {
42 | if(mBufferedSink == null) {
43 | mBufferedSink = Okio.buffer(sink(sink));
44 | }
45 |
46 | //写入
47 | mRequestBody.writeTo(mBufferedSink);
48 | //必须调用flush,否则最后一部分数据可能不会被写入
49 | mBufferedSink.flush();
50 | }
51 |
52 | /**
53 | * 写入,回调进度接口
54 | * @param sink Sink
55 | * @return Sink
56 | */
57 | private Sink sink(Sink sink) {
58 | return new ForwardingSink(sink) {
59 | //当前写入字节数
60 | long bytesWritten = 0L;
61 | //总字节长度,避免多次调用contentLength()方法
62 | long contentLength = 0L;
63 |
64 | @Override
65 | public void write(Buffer source, long byteCount) throws IOException {
66 | super.write(source, byteCount);
67 | if (contentLength == 0) {
68 | //获得contentLength的值,后续不再调用
69 | contentLength = contentLength();
70 | }
71 | //增加当前写入的字节数
72 | bytesWritten += byteCount;
73 | //回调
74 | mResponseHandler.onProgress(bytesWritten, contentLength);
75 | }
76 | };
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/body/ResponseProgressBody.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.body;
2 |
3 | import com.tsy.sdk.myokhttp.response.DownloadResponseHandler;
4 |
5 | import java.io.IOException;
6 |
7 | import okhttp3.MediaType;
8 | import okhttp3.ResponseBody;
9 | import okio.Buffer;
10 | import okio.BufferedSource;
11 | import okio.ForwardingSource;
12 | import okio.Okio;
13 | import okio.Source;
14 |
15 | /**
16 | * 重写responsebody 设置下载进度监听
17 | * Created by tsy on 16/8/16.
18 | */
19 | public class ResponseProgressBody extends ResponseBody {
20 |
21 | private ResponseBody mResponseBody;
22 | private DownloadResponseHandler mDownloadResponseHandler;
23 | private BufferedSource bufferedSource;
24 |
25 | public ResponseProgressBody(ResponseBody responseBody, DownloadResponseHandler downloadResponseHandler) {
26 | this.mResponseBody = responseBody;
27 | this.mDownloadResponseHandler = downloadResponseHandler;
28 | }
29 |
30 | @Override
31 | public MediaType contentType() {
32 | return mResponseBody.contentType();
33 | }
34 |
35 | @Override
36 | public long contentLength() {
37 | return mResponseBody.contentLength();
38 | }
39 |
40 | @Override
41 | public BufferedSource source() {
42 | if (bufferedSource == null) {
43 | bufferedSource = Okio.buffer(source(mResponseBody.source()));
44 | }
45 | return bufferedSource;
46 | }
47 |
48 | private Source source(Source source) {
49 |
50 | return new ForwardingSource(source) {
51 |
52 | long totalBytesRead;
53 |
54 | @Override
55 | public long read(Buffer sink, long byteCount) throws IOException {
56 | long bytesRead = super.read(sink, byteCount);
57 | totalBytesRead += ((bytesRead != -1) ? bytesRead : 0);
58 | if (mDownloadResponseHandler != null) {
59 | mDownloadResponseHandler.onProgress(totalBytesRead, mResponseBody.contentLength());
60 | }
61 | return bytesRead;
62 | }
63 | };
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/response/DownloadResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.response;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * 下载回调
7 | * Created by tsy on 16/8/16.
8 | */
9 | public abstract class DownloadResponseHandler {
10 |
11 | public abstract void onFinish(File download_file);
12 | public abstract void onProgress(long currentBytes, long totalBytes);
13 | public abstract void onFailure(String error_msg);
14 | }
15 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/response/GsonResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.response;
2 |
3 | import com.google.gson.internal.$Gson$Types;
4 |
5 | import java.lang.reflect.ParameterizedType;
6 | import java.lang.reflect.Type;
7 |
8 | /**
9 | * Gson类型的回调接口
10 | * Created by tsy on 16/8/15.
11 | */
12 | public abstract class GsonResponseHandler implements IResponseHandler {
13 |
14 | Type mType;
15 |
16 | public GsonResponseHandler() {
17 | Type myclass = getClass().getGenericSuperclass(); //反射获取带泛型的class
18 | if (myclass instanceof Class) {
19 | throw new RuntimeException("Missing type parameter.");
20 | }
21 | ParameterizedType parameter = (ParameterizedType) myclass; //获取所有泛型
22 | mType = $Gson$Types.canonicalize(parameter.getActualTypeArguments()[0]); //将泛型转为type
23 | }
24 |
25 | public final Type getType() {
26 | return mType;
27 | }
28 |
29 | public abstract void onSuccess(int statusCode, T response);
30 |
31 | @Override
32 | public void onProgress(long currentBytes, long totalBytes) {
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/response/IResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.response;
2 |
3 | /**
4 | * Created by tsy on 16/8/15.
5 | */
6 | public interface IResponseHandler {
7 |
8 | void onFailure(int statusCode, String error_msg);
9 |
10 | void onProgress(long currentBytes, long totalBytes);
11 | }
12 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/response/JsonResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.response;
2 |
3 | import org.json.JSONObject;
4 |
5 | /**
6 | * json类型的回调接口
7 | * Created by tsy on 16/8/15.
8 | */
9 | public abstract class JsonResponseHandler implements IResponseHandler {
10 |
11 | public abstract void onSuccess(int statusCode, JSONObject response);
12 |
13 | @Override
14 | public void onProgress(long currentBytes, long totalBytes) {
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/response/RawResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.response;
2 |
3 | /**
4 | * raw 字符串结果回调
5 | * Created by tsy on 16/8/18.
6 | */
7 | public abstract class RawResponseHandler implements IResponseHandler {
8 |
9 | public abstract void onSuccess(int statusCode, String response);
10 |
11 | @Override
12 | public void onProgress(long currentBytes, long totalBytes) {
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/myokhttp/src/main/java/com/tsy/sdk/myokhttp/util/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp.util;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by tsy on 16/8/15.
7 | */
8 | public class LogUtils {
9 |
10 | private static final String TAG = "LOGUTIL";
11 | private static boolean LOG_ENABLE = true;
12 | private static boolean DETAIL_ENABLE = true;
13 |
14 | private static String buildMsg(String msg) {
15 | StringBuilder buffer = new StringBuilder();
16 |
17 | // if (DETAIL_ENABLE) {
18 | // final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4];
19 | //
20 | // buffer.append("[ ");
21 | // buffer.append(Thread.currentThread().getName());
22 | // buffer.append(": ");
23 | // buffer.append(stackTraceElement.getFileName());
24 | // buffer.append(": ");
25 | // buffer.append(stackTraceElement.getLineNumber());
26 | // buffer.append(": ");
27 | // buffer.append(stackTraceElement.getMethodName());
28 | // }
29 |
30 | // buffer.append("() ] _____ ");
31 |
32 | buffer.append(msg);
33 |
34 | return buffer.toString();
35 | }
36 |
37 | /**
38 | * 设置是否显示Log
39 | * @param enable true-显示 false-不显示
40 | */
41 | public static void setLogEnable(boolean enable) {
42 | LOG_ENABLE = enable;
43 | }
44 |
45 | /**
46 | * 设置是否显示详细Log
47 | * @param isdetail true-显示详细 false-不显示详细
48 | */
49 | public static void setLogDetail(boolean isdetail) {
50 | DETAIL_ENABLE = isdetail;
51 | }
52 |
53 | /**
54 | * verbose log
55 | * @param msg log msg
56 | */
57 | public static void v(String msg) {
58 | if (LOG_ENABLE) {
59 | Log.v(TAG, buildMsg(msg));
60 | }
61 | }
62 |
63 | /**
64 | * verbose log
65 | * @param tag tag
66 | * @param msg log msg
67 | */
68 | public static void v(String tag, String msg) {
69 | if (LOG_ENABLE) {
70 | Log.v(tag, buildMsg(msg));
71 | }
72 | }
73 |
74 | /**
75 | * debug log
76 | * @param msg log msg
77 | */
78 | public static void d(String msg) {
79 | if (LOG_ENABLE) {
80 | Log.d(TAG, buildMsg(msg));
81 | }
82 | }
83 |
84 | /**
85 | * debug log
86 | * @param tag tag
87 | * @param msg log msg
88 | */
89 | public static void d(String tag, String msg) {
90 | if (LOG_ENABLE && Log.isLoggable(tag, Log.DEBUG)) {
91 | Log.d(tag, buildMsg(msg));
92 | }
93 | }
94 |
95 | /**
96 | * info log
97 | * @param msg log msg
98 | */
99 | public static void i(String msg) {
100 | if (LOG_ENABLE) {
101 | Log.i(TAG, buildMsg(msg));
102 | }
103 | }
104 |
105 | /**
106 | * info log
107 | * @param tag tag
108 | * @param msg log msg
109 | */
110 | public static void i(String tag, String msg) {
111 | if (LOG_ENABLE) {
112 | Log.i(tag, buildMsg(msg));
113 | }
114 | }
115 |
116 | /**
117 | * warning log
118 | * @param msg log msg
119 | */
120 | public static void w(String msg) {
121 | if (LOG_ENABLE) {
122 | Log.w(TAG, buildMsg(msg));
123 | }
124 | }
125 |
126 | /**
127 | * warning log
128 | * @param msg log msg
129 | * @param e exception
130 | */
131 | public static void w(String msg, Exception e) {
132 | if (LOG_ENABLE) {
133 | Log.w(TAG, buildMsg(msg), e);
134 | }
135 | }
136 |
137 | /**
138 | * warning log
139 | * @param tag tag
140 | * @param msg log msg
141 | */
142 | public static void w(String tag, String msg) {
143 | if (LOG_ENABLE) {
144 | Log.w(tag, buildMsg(msg));
145 | }
146 | }
147 |
148 | /**
149 | * warning log
150 | * @param tag tag
151 | * @param msg log msg
152 | * @param e exception
153 | */
154 | public static void w(String tag, String msg, Exception e) {
155 | if (LOG_ENABLE) {
156 | Log.w(tag, buildMsg(msg), e);
157 | }
158 | }
159 |
160 | /**
161 | * error log
162 | * @param msg log msg
163 | */
164 | public static void e(String msg) {
165 | if (LOG_ENABLE) {
166 | Log.e(TAG, buildMsg(msg));
167 | }
168 | }
169 |
170 | /**
171 | * error log
172 | * @param msg log msg
173 | * @param e exception
174 | */
175 | public static void e(String msg, Exception e) {
176 | if (LOG_ENABLE) {
177 | Log.e(TAG, buildMsg(msg), e);
178 | }
179 | }
180 |
181 | /**
182 | * error log
183 | * @param tag tag
184 | * @param msg msg
185 | */
186 | public static void e(String tag, String msg) {
187 | if (LOG_ENABLE) {
188 | Log.e(tag, buildMsg(msg));
189 | }
190 | }
191 |
192 | /**
193 | * error log
194 | * @param tag tag
195 | * @param msg log msg
196 | * @param e exception
197 | */
198 | public static void e(String tag, String msg, Exception e) {
199 | if (LOG_ENABLE) {
200 | Log.e(tag, buildMsg(msg), e);
201 | }
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/myokhttp/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MyOkhttp
3 |
4 |
--------------------------------------------------------------------------------
/myokhttp/src/test/java/com/tsy/sdk/myokhttp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myokhttp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/myutil/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/myutil/README.md:
--------------------------------------------------------------------------------
1 | # MyUtil Wiki
2 |
3 | > 该模块对通用的工具类进行封装,方便移植到其他项目直接使用
4 |
5 | ## 0 版本更新
6 |
7 | |日期|更新内容|
8 | |---|---|
9 | |2016-08-18|完成一些基本util的封装|
10 |
11 |
12 | ## 目录
13 |
14 | - BitmapUtils 主要负责Bitmap相关工具方法
15 | - DeviceUtils 设备属性相关工具类
16 | - HttpURLConnectionUtils 一个基于HttpURLConnection 简单网络请求工具类
17 | - LogUtils LOG工具类
18 | - ManifestUtils manifest工具类
19 | - MD5Utils MD5相关工具类
20 | - NetworkUtils 网络相关工具类
21 | - StringUtils 字符串相关方法
22 | - ToastUtils Toast相关方法
23 |
24 | ## 1 BitmapUtils
25 |
26 | > 主要负责Bitmap相关工具方法
27 |
28 | ### 1.1 Bitmap readBitMap(Context context, int resId)
29 |
30 | ```java
31 | /**
32 | * RGB_565方式读取资源到Bitmap
33 | * @param context 全局context
34 | * @param resId 资源id
35 | * @return bitmap
36 | */
37 | ```
38 |
39 | ### 1.2 Bitmap readBitMap(String path)
40 |
41 | ```java
42 | /**
43 | * RGB_565方式读取资源到Bitmap
44 | * @param path 文件图片路径
45 | * @return bitmap
46 | */
47 | ```
48 |
49 | ### 1.3 byte[] bitmap2Bytes(Bitmap bitmap)
50 |
51 | ```java
52 | /**
53 | * Bitmap 转 byte[]
54 | * @param bitmap 待转bitmap
55 | * @return 成功-byte[] 失败-null
56 | */
57 | ```
58 |
59 | ### 1.4 byte[] compressBitmap(byte[] datas, int byteCount)
60 |
61 | ```java
62 | /**
63 | * 压缩图片到指定byte大小 (在保证质量的情况下尽可能压缩 不保证压缩到指定字节)
64 | * @param datas 图片byte格式
65 | * @param byteCount 指定压缩到字节数
66 | * @return 压缩后的byte[] (不保证压缩到指定字节)
67 | */
68 | ```
69 |
70 | ## 2 DeviceUtils
71 |
72 | > 设备属性相关工具类
73 |
74 | ### 2.1 int getDeviceDpi(Context context)
75 |
76 | ```java
77 | /**
78 | * 获取设备密度
79 | * @param context 全局context
80 | * @return 设备dpi
81 | */
82 | ```
83 |
84 | ### 2.2 int[] getDeviceSize(Context context)
85 |
86 | ```java
87 | /**
88 | * 获取设备宽 高 单位像素
89 | * @param context 全局context
90 | * @return int[]
91 | * [0] 设备宽(像素)
92 | * [1] 设备高(像素)
93 | */
94 | ```
95 |
96 | ### 2.3 int dip2px(Context context, float dpValue)
97 |
98 | ```java
99 | /**
100 | * 根据手机的分辨率从从dp转成为px(像素)
101 | * @param context 全局context
102 | * @param dpValue dp值
103 | * @return px像素值
104 | */
105 | ```
106 |
107 | ### 2.4 int px2dip(Context context, float pxValue)
108 |
109 | ```java
110 | /**
111 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
112 | * @param context 全局context
113 | * @param pxValue px像素值
114 | * @return dp值
115 | */
116 | ```
117 |
118 | ## 3 HttpURLConnectionUtils
119 |
120 | > 一个基于HttpURLConnection 简单网络请求工具类
121 |
122 | ### 3.1 doPost(final String url, final Map params, final HttpResponseCallBack callback)
123 |
124 | ```java
125 | /**
126 | * 异步传输post请求 仅文本参数
127 | * @param url 请求地址
128 | * @param params 请求参数
129 | * @param callback 请求回调
130 | */
131 | ```
132 |
133 | ### 3.2 doPost(final String url, final Map params, final Map file, final HttpResponseCallBack callback)
134 |
135 | ```java
136 | /**
137 | * 异步传输post请求 文本 文件混合参数
138 | * @param url 请求地址
139 | * @param params 文本参数
140 | * @param file 上传文件参数
141 | * @param callback 请求回调
142 | */
143 | ```
144 |
145 | ### 3.3 doGet(final String url, final HttpResponseCallBack callback)
146 |
147 | ```java
148 | /**
149 | * 异步传输get请求
150 | * @param url 请求url
151 | * @param callback 请求回调
152 | */
153 | ```
154 |
155 | ## 4 LogUtils
156 |
157 | > LOG工具类 默认tag-LOGUTIL
158 |
159 | ### 4.1 void setLogEnable(boolean enable)
160 |
161 | ```java
162 | /**
163 | * 设置是否显示Log
164 | * @param enable true-显示 false-不显示
165 | */
166 | ```
167 |
168 | ### 4.2 void v(String msg) / void v(String tag, String msg)
169 |
170 | ```java
171 | /**
172 | * verbose log
173 | * @param tag tag
174 | * @param msg log msg
175 | */
176 | ```
177 |
178 | ### 4.3 其他的i, d, w, e 都类似以上格式
179 |
180 |
181 | ## 5 ManifestUtils
182 |
183 | > manifest工具类
184 |
185 | ### 5.1 String getMetaData(Context context, String key)
186 |
187 | ```java
188 | /**
189 | * 返回Manifest指定meta-data值
190 | * @param context 全局context
191 | * @param key meta-data key
192 | * @return
193 | * 成功-value
194 | * 失败-""
195 | */
196 | ```
197 |
198 | ### 5.2 String getVersionName(Context context)
199 |
200 | ```java
201 | /**
202 | * 获取版本名
203 | * @param context 全局context
204 | * @return versoin name
205 | */
206 | ```
207 |
208 | ## 6 MD5Utils
209 |
210 | > MD5相关工具类
211 |
212 | ### 6.1 String getMd5(String plainText)
213 |
214 | ```java
215 | /**
216 | * md5加密
217 | * @param plainText 待加密字符串
218 | * @return 加密后32位字符串
219 | */
220 | ```
221 |
222 | ## 7 NetworkUtils
223 |
224 | > 网络相关工具类
225 |
226 | ### 7.1 Boolean checkNetworkConnect(Context context)
227 |
228 | ```java
229 | /**
230 | * 检查网络是否连接
231 | * @param context 全局context
232 | * @return true 已连接 false 未连接
233 | */
234 | ```
235 |
236 | ## 8 StringUtils
237 |
238 | > 字符串相关方法
239 |
240 | ### 8.1 Boolean isEmpty(String str)
241 |
242 | ```java
243 | /**
244 | * 是否为空
245 | * @param str 字符串
246 | * @return true 空 false 非空
247 | */
248 | ```
249 |
250 | ## 9 ToastUtils
251 |
252 | > Toast相关方法
253 |
254 | ### 9.1 void showShort(Context context, int resId) / showLong(Context context, int resId)
255 |
256 | ```java
257 | /**
258 | * 显示short/long message
259 | * @param context 全局context
260 | * @param resId string string资源id
261 | */
262 | ```
263 |
264 | ### 9.2 void showShort(Context context, String message) / showLong(Context context, String message)
265 |
266 | ```java
267 | /**
268 | * 显示short/long message
269 | * @param context 全局context
270 | * @param message 显示msg
271 | */
272 | ```
--------------------------------------------------------------------------------
/myutil/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 9
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | testCompile 'junit:junit:4.12'
24 | compile 'com.android.support:appcompat-v7:23.4.0'
25 | }
26 |
--------------------------------------------------------------------------------
/myutil/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/tsy/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/myutil/src/androidTest/java/com/tsy/sdk/myutil/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/myutil/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/BitmapUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 |
7 | import java.io.ByteArrayOutputStream;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 |
11 | /**
12 | * Bitmap相关工具类
13 | * Created by tsy on 16/7/26.
14 | */
15 | public class BitmapUtils {
16 |
17 | private static final String TAG = "BitmapUtils";
18 |
19 | /**
20 | * RGB_565方式读取资源到Bitmap
21 | * @param context 全局context
22 | * @param resId 资源id
23 | * @return bitmap
24 | */
25 | public static Bitmap readBitMap(Context context, int resId) {
26 | BitmapFactory.Options opt = new BitmapFactory.Options();
27 | opt.inPreferredConfig = Bitmap.Config.RGB_565;
28 | opt.inPurgeable = true;
29 | opt.inInputShareable = true;
30 | InputStream is = context.getResources().openRawResource(resId);
31 | return BitmapFactory.decodeStream(is, null, opt);
32 | }
33 |
34 | /**
35 | * RGB_565方式读取资源到Bitmap
36 | * @param path 文件图片路径
37 | * @return bitmap
38 | */
39 | public static Bitmap readBitMap(String path) {
40 | BitmapFactory.Options opt = new BitmapFactory.Options();
41 | opt.inPreferredConfig = Bitmap.Config.RGB_565;
42 | opt.inPurgeable = true;
43 | opt.inInputShareable = true;
44 | return BitmapFactory.decodeFile(path, opt);
45 | }
46 |
47 | /**
48 | * Bitmap 转 byte[]
49 | * @param bitmap 待转bitmap
50 | * @return 成功-byte[] 失败-null
51 | */
52 | public static byte[] bitmap2Bytes(Bitmap bitmap) {
53 | ByteArrayOutputStream byteArrayOutputStream = null;
54 | if(bitmap != null && !bitmap.isRecycled()) {
55 | try {
56 | byteArrayOutputStream = new ByteArrayOutputStream();
57 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
58 | if(byteArrayOutputStream.toByteArray() == null) {
59 | LogUtils.e(TAG, "bitmap2Bytes byteArrayOutputStream toByteArray=null");
60 | }
61 | return byteArrayOutputStream.toByteArray();
62 | } catch (Exception e) {
63 | LogUtils.e(TAG, "bitmap2Bytes exception", e);
64 | } finally {
65 | if(byteArrayOutputStream != null) {
66 | try {
67 | byteArrayOutputStream.close();
68 | } catch (IOException var14) {
69 | ;
70 | }
71 | }
72 | }
73 |
74 | return null;
75 | } else {
76 | LogUtils.e(TAG, "bitmap2Bytes bitmap == null or bitmap.isRecycled()");
77 | return null;
78 | }
79 | }
80 |
81 | /**
82 | * 压缩图片到指定byte大小 (在保证质量的情况下尽可能压缩 不保证压缩到指定字节)
83 | * @param datas 图片byte格式
84 | * @param byteCount 指定压缩到字节数
85 | * @return 压缩后的byte[] (不保证压缩到指定字节)
86 | */
87 | public static byte[] compressBitmap(byte[] datas, int byteCount) {
88 | boolean isFinish = false;
89 | if(datas != null && datas.length > byteCount) {
90 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
91 | Bitmap tmpBitmap = BitmapFactory.decodeByteArray(datas, 0, datas.length);
92 | int times = 1;
93 | double percentage = 1.0D;
94 |
95 | while(!isFinish && times <= 10) {
96 | percentage = Math.pow(0.8D, (double)times);
97 | int compress_datas = (int)(100.0D * percentage);
98 | tmpBitmap.compress(Bitmap.CompressFormat.JPEG, compress_datas, outputStream);
99 | if(outputStream != null && outputStream.size() < byteCount) {
100 | isFinish = true;
101 | } else {
102 | outputStream.reset();
103 | ++times;
104 | }
105 | }
106 |
107 | if(outputStream != null) {
108 | byte[] outputStreamByte = outputStream.toByteArray();
109 | if(!tmpBitmap.isRecycled()) {
110 | tmpBitmap.recycle();
111 | }
112 |
113 | if(outputStreamByte.length > byteCount) {
114 | LogUtils.e(TAG, "compressBitmap cannot compress to " + byteCount + ", after compress size=" + outputStreamByte.length);
115 | }
116 |
117 | return outputStreamByte;
118 | }
119 | }
120 |
121 | return datas;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/DeviceUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 |
6 | /**
7 | * 设备属性相关工具类
8 | * Created by tsy on 16/7/25.
9 | */
10 | public class DeviceUtils {
11 |
12 | /**
13 | * 获取设备密度
14 | * @param context 全局context
15 | * @return 设备dpi
16 | */
17 | public static int getDeviceDpi(Context context) {
18 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
19 | return dm.densityDpi;
20 | }
21 |
22 | /**
23 | * 获取设备宽 高 单位像素
24 | * @param context 全局context
25 | * @return int[]
26 | * [0] 设备宽(像素)
27 | * [1] 设备高(像素)
28 | */
29 | public static int[] getDeviceSize(Context context) {
30 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
31 | return new int[]{dm.widthPixels, dm.heightPixels};
32 | }
33 |
34 | /**
35 | * 根据手机的分辨率从从dp转成为px(像素)
36 | * @param context 全局context
37 | * @param dpValue dp值
38 | * @return px像素值
39 | */
40 | public static int dip2px(Context context, float dpValue) {
41 | final float scale = context.getResources().getDisplayMetrics().density;
42 | return (int) (dpValue * scale + 0.5f);
43 | }
44 |
45 | /**
46 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
47 | * @param context 全局context
48 | * @param pxValue px像素值
49 | * @return dp值
50 | */
51 | public static int px2dip(Context context, float pxValue) {
52 | final float scale = context.getResources().getDisplayMetrics().density;
53 | return (int) (pxValue / scale + 0.5f);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/HttpURLConnectionUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.accounts.NetworkErrorException;
4 | import android.annotation.TargetApi;
5 | import android.os.Build;
6 | import android.os.Handler;
7 |
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | import java.io.BufferedReader;
12 | import java.io.DataOutputStream;
13 | import java.io.File;
14 | import java.io.FileInputStream;
15 | import java.io.InputStream;
16 | import java.io.InputStreamReader;
17 | import java.net.HttpURLConnection;
18 | import java.net.URL;
19 | import java.util.Iterator;
20 | import java.util.Map;
21 |
22 | /**
23 | * 一个基于HttpURLConnection 简单网络请求工具类
24 | * Created by tsy on 16/8/15.
25 | */
26 | public class HttpURLConnectionUtils {
27 | /**
28 | * 请求结果回调接口
29 | */
30 | public interface HttpResponseCallBack {
31 | void onSuccess(JSONObject response); //返回数据
32 | void onFailure(); //网络连接错误 json解析错误
33 | }
34 |
35 | /**
36 | * 异步传输post请求 仅文本参数
37 | * @param url 请求地址
38 | * @param params 请求参数
39 | * @param callback 请求回调
40 | */
41 | public static void doPost(final String url, final Map params, final HttpResponseCallBack callback) {
42 | final Handler handler = new Handler();
43 | new Thread(new Runnable() {
44 | @Override
45 | public void run() {
46 | final String response = post(url, params, null);
47 | handler.post(new Runnable() {
48 | @Override
49 | public void run() {
50 | if (response == null) {
51 | callback.onFailure();
52 | return;
53 | }
54 | try {
55 | JSONObject json = new JSONObject(response);
56 | callback.onSuccess(json);
57 | } catch (JSONException e) {
58 | callback.onFailure();
59 | }
60 | }
61 | });
62 | }
63 | }).start();
64 | }
65 |
66 | /**
67 | * 异步传输post请求 文本 文件混合参数
68 | * @param url 请求地址
69 | * @param params 文本参数
70 | * @param file 上传文件参数
71 | * @param callback 请求回调
72 | */
73 | public static void doPost(final String url, final Map params, final Map file, final HttpResponseCallBack callback) {
74 | final Handler handler = new Handler();
75 | new Thread(new Runnable() {
76 | @Override
77 | public void run() {
78 | final String response = post(url, params, file);
79 | handler.post(new Runnable() {
80 | @Override
81 | public void run() {
82 | if (response == null) {
83 | callback.onFailure();
84 | return;
85 | }
86 | try {
87 | JSONObject json = new JSONObject(response);
88 | callback.onSuccess(json);
89 | } catch (JSONException e) {
90 | callback.onFailure();
91 | }
92 | }
93 | });
94 | }
95 | }).start();
96 | }
97 |
98 | /**
99 | * 异步传输get请求
100 | * @param url 请求url
101 | * @param callback 请求回调
102 | */
103 | public static void doGet(final String url, final HttpResponseCallBack callback) {
104 | final Handler handler = new Handler();
105 | new Thread(new Runnable() {
106 | @Override
107 | public void run() {
108 | final String response = get(url);
109 | handler.post(new Runnable() {
110 | @Override
111 | public void run() {
112 | if(response == null) {
113 | callback.onFailure();
114 | return;
115 | }
116 | try {
117 | JSONObject json = new JSONObject(response);
118 | callback.onSuccess(json);
119 | } catch (JSONException e) {
120 | callback.onFailure();
121 | }
122 | }
123 | });
124 | }
125 | }).start();
126 | }
127 |
128 | /**
129 | * 使用HttpURLConnection进行post请求
130 | * @param url 请求地址
131 | * @param params 请求参数 key-val
132 | * @param files 上传的文件 key-file path
133 | * @return 请求返回值
134 | */
135 | @TargetApi(Build.VERSION_CODES.ECLAIR)
136 | private static String post(String url, Map params, Map files) {
137 | HttpURLConnection conn = null;
138 |
139 | //http content 头尾等信息
140 | String PREFIX = "--"; //前缀
141 | String BOUNDARY = "*****"+Long.toString(System.currentTimeMillis())+"*****"; //自定义分割串
142 | String END = "\r\n"; //结束
143 |
144 | try {
145 | //创建连接
146 | URL mURL = new URL(url); // 创建一个URL对象
147 | conn = (HttpURLConnection) mURL.openConnection(); // 调用URL的openConnection()方法,获取HttpURLConnection对象
148 |
149 | conn.setReadTimeout(5000);// 设置读取超时为5秒
150 | conn.setConnectTimeout(10000);// 设置连接网络超时为10秒
151 |
152 | // 允许Input、Output,不使用Cache
153 | conn.setDoInput(true);
154 | conn.setDoOutput(true);
155 | conn.setUseCaches(false);
156 |
157 | conn.setRequestMethod("POST");// 设置请求方法为post
158 | conn.setRequestProperty("Connection", "Keep-Alive");
159 | conn.setRequestProperty("Charset", "UTF-8");
160 | conn.setRequestProperty("User-Agent", "Android Multipart HTTP Client 1.0");
161 | conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
162 |
163 | DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream());
164 |
165 | //post文件
166 | if(files != null && !files.isEmpty()) {
167 | Iterator> iterator = files.entrySet().iterator();
168 | while (iterator.hasNext()) {
169 | Map.Entry param = iterator.next();
170 | String file_param_name = param.getKey(); //参数名
171 | String file_path = param.getValue(); //路径
172 | String filename = file_path.substring(file_path.lastIndexOf("/") + 1); //文件名
173 |
174 | File file = new File(file_path);
175 | if(file == null || !file.exists()) {
176 | continue;
177 | }
178 |
179 | //头部
180 | StringBuilder sb = new StringBuilder();
181 | sb.append(PREFIX + BOUNDARY + END);
182 | sb.append("Content-Disposition: form-data; name=" + "\"" + file_param_name +
183 | "\";filename=\"" + filename + "\"" + END);
184 | sb.append("Content-Type: application/octet-stream; charset=UTF-8" + END);
185 | sb.append(END);
186 | outputStream.writeBytes(sb.toString());
187 |
188 | // 取得文件的FileInputStream
189 | FileInputStream fis = new FileInputStream(file_path);
190 | byte[] buffer = new byte[1024];
191 | int length = -1;
192 | // 从文件读取数据至缓冲区
193 | while ((length = fis.read(buffer)) != -1) {
194 | outputStream.write(buffer, 0, length);
195 | }
196 | fis.close();
197 |
198 | outputStream.writeBytes(END);
199 | }
200 | }
201 |
202 | // post文本参数
203 | if(params != null && !params.isEmpty()) {
204 | Iterator> iterator = params.entrySet().iterator();
205 | while (iterator.hasNext()) {
206 | Map.Entry param = iterator.next();
207 | String key = param.getKey();
208 | String value = param.getValue();
209 |
210 | if(key == null || value == null) {
211 | continue;
212 | }
213 | outputStream.writeBytes(PREFIX + BOUNDARY + END);
214 | outputStream.writeBytes("Content-Disposition: form-data; name=" + "\"" + key + "\"" + END);
215 | outputStream.writeBytes("Content-Type: text/plain; charset=UTF-8" + END);
216 | outputStream.writeBytes(END);
217 | outputStream.write(value.getBytes("UTF-8"));
218 | outputStream.writeBytes(END);
219 | }
220 | }
221 |
222 | outputStream.writeBytes(PREFIX + BOUNDARY + END);
223 | outputStream.flush();
224 | outputStream.close();
225 |
226 | //请求返回
227 | int responseCode = conn.getResponseCode();// 调用此方法就不必再使用conn.connect()方法
228 | if (responseCode == HttpURLConnection.HTTP_OK) {
229 | InputStream is = conn.getInputStream(); //获得输入流
230 | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); //包装字节流为字符流
231 | StringBuilder response = new StringBuilder();
232 | String line;
233 | while ((line = reader.readLine()) != null) {
234 | response.append(line);
235 | }
236 | if(is != null) {
237 | is.close();
238 | }
239 |
240 | return response.toString();
241 | } else {
242 | throw new NetworkErrorException("response status is " + responseCode);
243 | }
244 |
245 | } catch (Exception e) {
246 | e.printStackTrace();
247 | return null;
248 | } finally {
249 | if (conn != null) {
250 | conn.disconnect(); // 关闭连接
251 | }
252 | }
253 | }
254 |
255 | /**
256 | * 使用HttpURLConnection进行get请求
257 | * @param url 请求地址
258 | * @return 请求返回值
259 | */
260 | @TargetApi(Build.VERSION_CODES.ECLAIR)
261 | private static String get(String url) {
262 | HttpURLConnection conn = null;
263 | try {
264 | //创建连接
265 | URL mURL = new URL(url);
266 | conn = (HttpURLConnection) mURL.openConnection();
267 | conn.setRequestMethod("GET");
268 | conn.setReadTimeout(5000);
269 | conn.setConnectTimeout(10000);
270 |
271 | //请求返回
272 | int responseCode = conn.getResponseCode();
273 | if (responseCode == HttpURLConnection.HTTP_OK) {
274 | InputStream is = conn.getInputStream(); //获得输入流
275 | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); //包装字节流为字符流
276 | StringBuilder response = new StringBuilder();
277 | String line;
278 | while ((line = reader.readLine()) != null) {
279 | response.append(line);
280 | }
281 | if(is != null) {
282 | is.close();
283 | }
284 |
285 | return response.toString();
286 | } else {
287 | throw new NetworkErrorException("response status is " + responseCode);
288 | }
289 |
290 | } catch (Exception e) {
291 | e.printStackTrace();
292 | return null;
293 | } finally {
294 | if (conn != null) {
295 | conn.disconnect(); // 关闭连接
296 | }
297 | }
298 | }
299 | }
300 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * LOG工具类 默认tag-LOGUTIL
7 | * Created by tsy on 16/8/15.
8 | */
9 | public class LogUtils {
10 |
11 | private static final String TAG = "LOGUTIL";
12 | private static boolean LOG_ENABLE = true;
13 | private static boolean DETAIL_ENABLE = true;
14 |
15 | private static String buildMsg(String msg) {
16 | StringBuilder buffer = new StringBuilder();
17 |
18 | // if (DETAIL_ENABLE) {
19 | // final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4];
20 | //
21 | // buffer.append("[ ");
22 | // buffer.append(Thread.currentThread().getName());
23 | // buffer.append(": ");
24 | // buffer.append(stackTraceElement.getFileName());
25 | // buffer.append(": ");
26 | // buffer.append(stackTraceElement.getLineNumber());
27 | // buffer.append(": ");
28 | // buffer.append(stackTraceElement.getMethodName());
29 | // }
30 |
31 | // buffer.append("() ] _____ ");
32 |
33 | buffer.append(msg);
34 |
35 | return buffer.toString();
36 | }
37 |
38 | /**
39 | * 设置是否显示Log
40 | * @param enable true-显示 false-不显示
41 | */
42 | public static void setLogEnable(boolean enable) {
43 | LOG_ENABLE = enable;
44 | }
45 |
46 | // /**
47 | // * 设置是否显示详细Log
48 | // * @param isdetail true-显示详细 false-不显示详细
49 | // */
50 | // public static void setLogDetail(boolean isdetail) {
51 | // DETAIL_ENABLE = isdetail;
52 | // }
53 |
54 | /**
55 | * verbose log
56 | * @param msg log msg
57 | */
58 | public static void v(String msg) {
59 | if (LOG_ENABLE) {
60 | Log.v(TAG, buildMsg(msg));
61 | }
62 | }
63 |
64 | /**
65 | * verbose log
66 | * @param tag tag
67 | * @param msg log msg
68 | */
69 | public static void v(String tag, String msg) {
70 | if (LOG_ENABLE) {
71 | Log.v(tag, buildMsg(msg));
72 | }
73 | }
74 |
75 | /**
76 | * debug log
77 | * @param msg log msg
78 | */
79 | public static void d(String msg) {
80 | if (LOG_ENABLE) {
81 | Log.d(TAG, buildMsg(msg));
82 | }
83 | }
84 |
85 | /**
86 | * debug log
87 | * @param tag tag
88 | * @param msg log msg
89 | */
90 | public static void d(String tag, String msg) {
91 | if (LOG_ENABLE && Log.isLoggable(tag, Log.DEBUG)) {
92 | Log.d(tag, buildMsg(msg));
93 | }
94 | }
95 |
96 | /**
97 | * info log
98 | * @param msg log msg
99 | */
100 | public static void i(String msg) {
101 | if (LOG_ENABLE) {
102 | Log.i(TAG, buildMsg(msg));
103 | }
104 | }
105 |
106 | /**
107 | * info log
108 | * @param tag tag
109 | * @param msg log msg
110 | */
111 | public static void i(String tag, String msg) {
112 | if (LOG_ENABLE) {
113 | Log.i(tag, buildMsg(msg));
114 | }
115 | }
116 |
117 | /**
118 | * warning log
119 | * @param msg log msg
120 | */
121 | public static void w(String msg) {
122 | if (LOG_ENABLE) {
123 | Log.w(TAG, buildMsg(msg));
124 | }
125 | }
126 |
127 | /**
128 | * warning log
129 | * @param msg log msg
130 | * @param e exception
131 | */
132 | public static void w(String msg, Exception e) {
133 | if (LOG_ENABLE) {
134 | Log.w(TAG, buildMsg(msg), e);
135 | }
136 | }
137 |
138 | /**
139 | * warning log
140 | * @param tag tag
141 | * @param msg log msg
142 | */
143 | public static void w(String tag, String msg) {
144 | if (LOG_ENABLE) {
145 | Log.w(tag, buildMsg(msg));
146 | }
147 | }
148 |
149 | /**
150 | * warning log
151 | * @param tag tag
152 | * @param msg log msg
153 | * @param e exception
154 | */
155 | public static void w(String tag, String msg, Exception e) {
156 | if (LOG_ENABLE) {
157 | Log.w(tag, buildMsg(msg), e);
158 | }
159 | }
160 |
161 | /**
162 | * error log
163 | * @param msg log msg
164 | */
165 | public static void e(String msg) {
166 | if (LOG_ENABLE) {
167 | Log.e(TAG, buildMsg(msg));
168 | }
169 | }
170 |
171 | /**
172 | * error log
173 | * @param msg log msg
174 | * @param e exception
175 | */
176 | public static void e(String msg, Exception e) {
177 | if (LOG_ENABLE) {
178 | Log.e(TAG, buildMsg(msg), e);
179 | }
180 | }
181 |
182 | /**
183 | * error log
184 | * @param tag tag
185 | * @param msg msg
186 | */
187 | public static void e(String tag, String msg) {
188 | if (LOG_ENABLE) {
189 | Log.e(tag, buildMsg(msg));
190 | }
191 | }
192 |
193 | /**
194 | * error log
195 | * @param tag tag
196 | * @param msg log msg
197 | * @param e exception
198 | */
199 | public static void e(String tag, String msg, Exception e) {
200 | if (LOG_ENABLE) {
201 | Log.e(tag, buildMsg(msg), e);
202 | }
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/MD5Utils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import java.security.MessageDigest;
4 | import java.security.NoSuchAlgorithmException;
5 |
6 | /**
7 | * MD5相关工具类
8 | * Created by tsy on 16/8/15.
9 | */
10 | public class MD5Utils {
11 |
12 | private static final String TAG = "MD5Utils";
13 |
14 | /**
15 | * md5加密
16 | * @param plainText 待加密字符串
17 | * @return 加密后32位字符串
18 | */
19 | public static String getMd5(String plainText) {
20 |
21 | try {
22 | MessageDigest md = MessageDigest.getInstance("MD5");
23 | md.update(plainText.getBytes());
24 | byte b[] = md.digest();
25 |
26 | int i;
27 |
28 | StringBuffer buf = new StringBuffer("");
29 | for (int offset = 0; offset < b.length; offset++) {
30 | i = b[offset];
31 | if (i < 0)
32 | i += 256;
33 | if (i < 16)
34 | buf.append("0");
35 | buf.append(Integer.toHexString(i));
36 | }
37 | //32位加密
38 | return buf.toString();
39 | } catch (NoSuchAlgorithmException e) {
40 | LogUtils.e(TAG, "getMd5 error", e);
41 | return null;
42 | }
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/ManifestUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ApplicationInfo;
5 | import android.content.pm.PackageInfo;
6 | import android.content.pm.PackageManager;
7 |
8 | /**
9 | * manifest工具类
10 | * Created by tsy on 16/7/25.
11 | */
12 | public class ManifestUtils {
13 |
14 | private static final String TAG = "ManifestUtils";
15 |
16 | /**
17 | * 返回Manifest指定meta-data值
18 | * @param context 全局context
19 | * @param key meta-data key
20 | * @return
21 | * 成功-value
22 | * 失败-""
23 | */
24 | public static String getMetaData(Context context, String key) {
25 | ApplicationInfo app_info = null;
26 | try {
27 | app_info = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
28 | if(app_info == null || app_info.metaData == null) {
29 | return "";
30 | } else {
31 | Object obj = app_info.metaData.get(key);
32 | if(obj != null) {
33 | return obj.toString();
34 | } else {
35 | return "";
36 | }
37 | }
38 | } catch (PackageManager.NameNotFoundException e) {
39 | LogUtils.e(TAG, "getMetaData error", e);
40 | return "";
41 | }
42 | }
43 |
44 | /**
45 | * 获取版本名
46 | * @param context 全局context
47 | * @return versoin name
48 | */
49 | public static String getVersionName(Context context) {
50 | String version = "0.0";
51 | try {
52 | PackageManager packageManager = context.getPackageManager();
53 | PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
54 | version = packInfo.versionName;
55 | } catch (Exception e) {
56 | LogUtils.e(TAG, "getVersionName error", e);
57 | }
58 |
59 | return version;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/NetworkUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | /**
8 | * 网络相关工具类
9 | * Created by tsy on 16/7/21.
10 | */
11 | public class NetworkUtils {
12 |
13 | /**
14 | * 检查网络是否连接
15 | * @param context 全局context
16 | * @return true 已连接 false 未连接
17 | */
18 | public static Boolean checkNetworkConnect(Context context) {
19 | if (context != null) {
20 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
21 | NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
22 | if (mNetworkInfo != null) {
23 | return mNetworkInfo.isAvailable();
24 | }
25 | }
26 |
27 | return false;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | /**
4 | * 字符串相关方法
5 | * Created by tsy on 16/8/15.
6 | */
7 | public class StringUtils {
8 |
9 | /**
10 | * 是否为空
11 | * @param str 字符串
12 | * @return true 空 false 非空
13 | */
14 | public static Boolean isEmpty(String str) {
15 | if(str == null || str.equals("")) {
16 | return true;
17 | }
18 |
19 | return false;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/myutil/src/main/java/com/tsy/sdk/myutil/ToastUtils.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 | /**
7 | * Toast相关方法
8 | * Created by tsy on 16/8/15.
9 | */
10 | public class ToastUtils {
11 |
12 | /**
13 | * 显示short message
14 | * @param context 全局context
15 | * @param resId string string资源id
16 | */
17 | public static void showShort(Context context, int resId) {
18 | Toast.makeText(context, resId, Toast.LENGTH_SHORT).show();
19 | }
20 |
21 | /**
22 | * 显示short message
23 | * @param context 全局context
24 | * @param message 显示msg
25 | */
26 | public static void showShort(Context context, String message) {
27 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
28 | }
29 |
30 | /**
31 | * 显示long message
32 | * @param context 全局context
33 | * @param resId string string资源id
34 | */
35 | public static void showLong(Context context, int resId) {
36 | Toast.makeText(context, resId, Toast.LENGTH_LONG).show();
37 | }
38 |
39 | /**
40 | * 显示long message
41 | * @param context 全局context
42 | * @param message 显示msg
43 | */
44 | public static void showLong(Context context, String message) {
45 | Toast.makeText(context, message, Toast.LENGTH_LONG).show();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/myutil/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MyUtil
3 |
4 |
--------------------------------------------------------------------------------
/myutil/src/test/java/com/tsy/sdk/myutil/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.tsy.sdk.myutil;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':myokhttp', ':myutil'
2 |
--------------------------------------------------------------------------------