├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── qaplug_profiles.xml
└── runConfigurations.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── butterknife-6.0.0.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── zone
│ │ └── forgithubproject
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── zone
│ │ │ └── forgithubproject
│ │ │ ├── AdActivity.java
│ │ │ ├── LoginActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── WebViewActivity.java
│ │ │ ├── base
│ │ │ ├── BaseActivity.java
│ │ │ ├── BaseBean.java
│ │ │ ├── IBaseView.java
│ │ │ ├── IPBase.java
│ │ │ └── PBase.java
│ │ │ ├── contract
│ │ │ ├── AdContract.java
│ │ │ ├── LoginContract.java
│ │ │ └── MainContract.java
│ │ │ ├── model
│ │ │ ├── AdModelImpl.java
│ │ │ ├── LoginModelImpl.java
│ │ │ ├── MainModelImpl.java
│ │ │ └── bean
│ │ │ │ ├── AdMessageBean.java
│ │ │ │ └── LoginCheckBean.java
│ │ │ ├── myApplication
│ │ │ └── MyApplication.java
│ │ │ ├── presenter
│ │ │ ├── AdPresenterImpl.java
│ │ │ ├── LoginPresenterImpl.java
│ │ │ └── MainPresenterImpl.java
│ │ │ ├── service
│ │ │ ├── RetrofitService.java
│ │ │ └── RetrofitServiceInstance.java
│ │ │ ├── utils
│ │ │ ├── L.java
│ │ │ ├── NetUtils.java
│ │ │ ├── Rx
│ │ │ │ ├── RxHelper.java
│ │ │ │ └── RxSubscribe.java
│ │ │ ├── SPUtils.java
│ │ │ └── T.java
│ │ │ └── weidge
│ │ │ └── ProgressWebView.java
│ └── res
│ │ ├── drawable
│ │ ├── jyz_png.png
│ │ ├── splash_jyz.jpg
│ │ └── splash_skip.xml
│ │ ├── layout
│ │ ├── activity_ad.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_webview.xml
│ │ └── head.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
│ └── zone
│ └── forgithubproject
│ └── ExampleUnitTest.java
├── build.gradle
├── freeline.py
├── freeline
├── freeline.py
├── freeline_core
│ ├── .idea
│ │ ├── dictionaries
│ │ │ └── huangyong.xml
│ │ ├── inspectionProfiles
│ │ │ ├── Project_Default.xml
│ │ │ └── profiles_settings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ ├── vcs.xml
│ │ └── workspace.xml
│ ├── __init__.py
│ ├── android_tools.py
│ ├── build_commands.py
│ ├── builder.py
│ ├── command.py
│ ├── cursor.py
│ ├── dispatcher.py
│ ├── exceptions.py
│ ├── freeline_build.py
│ ├── gradle_clean_build.py
│ ├── gradle_inc_build.py
│ ├── gradle_tools.py
│ ├── hackwindows.py
│ ├── init.py
│ ├── logger.py
│ ├── sync_client.py
│ ├── task.py
│ ├── task_engine.py
│ ├── terminal.py
│ ├── tracing.py
│ ├── utils.py
│ └── version.py
└── release-tools
│ ├── DexMerge.jar
│ ├── FreelineAapt
│ ├── FreelineAapt.exe
│ ├── FreelineAapt_
│ ├── databinding-cli.jar
│ ├── databinding-cli8.jar
│ ├── dexmerger
│ ├── dx
│ ├── dx.bat
│ ├── dx.jar
│ ├── jasmin
│ ├── jasmin.jar
│ ├── lib64
│ └── libc++.so
│ ├── mainDexClasses
│ ├── mainDexClasses.bat
│ ├── mainDexClasses.rules
│ └── manifest.txt
├── freeline_core
├── .idea
│ ├── dictionaries
│ │ └── huangyong.xml
│ ├── inspectionProfiles
│ │ ├── Project_Default.xml
│ │ └── profiles_settings.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── vcs.xml
│ └── workspace.xml
├── __init__.py
├── android_tools.py
├── build_commands.py
├── builder.py
├── command.py
├── cursor.py
├── dispatcher.py
├── exceptions.py
├── freeline_build.py
├── gradle_clean_build.py
├── gradle_inc_build.py
├── gradle_tools.py
├── hackwindows.py
├── init.py
├── logger.py
├── sync_client.py
├── task.py
├── task_engine.py
├── terminal.py
├── tracing.py
├── utils.py
└── version.py
├── freeline_project_description.json
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'com.antfortune.freeline'
3 |
4 | android {
5 | compileSdkVersion 24
6 | buildToolsVersion "24.0.3"
7 | defaultConfig {
8 | applicationId "com.zone.forgithubproject"
9 | minSdkVersion 15
10 | targetSdkVersion 24
11 | versionCode 1
12 | versionName "1.0"
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | }
22 |
23 | dependencies {
24 | compile fileTree(include: ['*.jar'], dir: 'libs')
25 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
26 | exclude group: 'com.android.support', module: 'support-annotations'
27 | })
28 | compile 'com.android.support:appcompat-v7:24.2.1'
29 | testCompile 'junit:junit:4.12'
30 | compile 'com.zhy:autolayout:1.4.5'
31 |
32 | compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
33 | compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
34 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
35 |
36 | compile 'io.reactivex:rxandroid:1.2.0'
37 | compile 'io.reactivex:rxjava:1.1.0'
38 |
39 |
40 | compile 'com.android.support:design:24.2.0'
41 | compile files('libs/butterknife-6.0.0.jar')
42 | compile 'com.github.bumptech.glide:glide:3.7.0'
43 |
44 | compile 'com.squareup.okhttp3:okhttp:3.0.1'
45 | compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/libs/butterknife-6.0.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/libs/butterknife-6.0.0.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 Z:\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/zone/forgithubproject/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.zone.forgithubproject", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
27 | >
28 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/AdActivity.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject;
2 |
3 | import android.content.Intent;
4 | import android.graphics.Bitmap;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.Message;
8 | import android.text.TextUtils;
9 | import android.view.View;
10 | import android.view.WindowManager;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import com.bumptech.glide.Glide;
16 | import com.zone.forgithubproject.myApplication.MyApplication;
17 | import com.zone.forgithubproject.base.BaseActivity;
18 | import com.zone.forgithubproject.contract.AdContract;
19 | import com.zone.forgithubproject.model.bean.LoginCheckBean;
20 | import com.zone.forgithubproject.presenter.AdPresenterImpl;
21 | import com.zone.forgithubproject.utils.L;
22 | import com.zone.forgithubproject.utils.NetUtils;
23 | import com.zone.forgithubproject.utils.SPUtils;
24 |
25 | import butterknife.ButterKnife;
26 | import butterknife.InjectView;
27 | import butterknife.OnClick;
28 |
29 |
30 |
31 | /**
32 | * Created by zone on 2016/7/18.
33 | */
34 | public class AdActivity extends BaseActivity implements AdContract.View {
35 | @InjectView(R.id.tv_second)
36 | TextView tvSecond;
37 | @InjectView(R.id.layout_skip)
38 | LinearLayout layoutSkip;
39 | int timeCount = 0;
40 | boolean continueCount = true;
41 | @InjectView(R.id.iv_advertising)
42 | ImageView ivAdvertising;
43 | private LoginCheckBean loginCheckBean;
44 | Handler handler = new Handler() {
45 | @Override
46 | public void handleMessage(Message msg) {
47 | super.handleMessage(msg);
48 | countNum();
49 | if (continueCount) {
50 | handler.sendMessageDelayed(handler.obtainMessage(-1),1000);
51 | }
52 | }
53 | };
54 | private Bitmap bitmap;
55 | private AdPresenterImpl pAd;
56 | private int initTimeCount;
57 |
58 |
59 | @Override
60 | protected void onCreate(Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 | setContentView(R.layout.activity_ad);
63 | ButterKnife.inject(this);
64 | pAd = new AdPresenterImpl();
65 | pAd.attachView(this);
66 | initTimeCount = 6;
67 | loginCheckBean = new LoginCheckBean();
68 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
69 | if (NetUtils.isConnected(AdActivity.this)) {
70 | pAd.getLoginCheck();
71 | }
72 | layoutSkip.setVisibility(View.INVISIBLE);
73 | handler.sendMessageDelayed(handler.obtainMessage(-1),1000);
74 | }
75 |
76 |
77 | @OnClick({R.id.iv_advertising, R.id.layout_skip})
78 | public void onClick(View view) {
79 | switch (view.getId()) {
80 | case R.id.iv_advertising:
81 | String url = (String) SPUtils.get(this, "adUrl", "null");
82 | if (!url.equals("null")) {
83 | continueCount = false;
84 | Intent intent = new Intent(AdActivity.this, WebViewActivity.class);
85 | intent.putExtra("title", "震惊,程序员竟然如此写代码,真相竟然是这个...");
86 | intent.putExtra("url", url);
87 | intent.putExtra("from", "advertising");
88 | startActivity(intent);
89 | finish();
90 | }
91 | break;
92 | case R.id.layout_skip:
93 | continueCount = false;
94 | toNextActivity();
95 | finish();
96 | break;
97 | }
98 | }
99 |
100 |
101 | private int countNum() {//数秒
102 | timeCount++;
103 | if (timeCount == 3) {//数秒,超过3秒后如果没有网络,则进入下一个页面
104 | if (!NetUtils.isConnected(AdActivity.this)) {
105 | continueCount = false;
106 | toNextActivity();
107 | finish();
108 | }
109 | if (!loginCheckBean.isPlayAd()) {//如果服务端不允许播放广告,则直接进入下一个页面
110 | continueCount = false;
111 | toNextActivity();
112 | finish();
113 | } else {//如果播放,则获取本地的图片
114 | ivAdvertising.setVisibility(View.VISIBLE);
115 | layoutSkip.setVisibility(View.VISIBLE);
116 | }
117 | }
118 | if (timeCount == initTimeCount) {
119 | continueCount = false;
120 | toNextActivity();
121 | finish();
122 | }
123 | return timeCount;
124 | }
125 |
126 | public void toNextActivity() {//根据是否保存有 token 判断去登录界面还是主界面
127 | L.d("到下一个界面");
128 | Intent intent = null;
129 | String token = (String) SPUtils.get(AdActivity.this, "token", "");
130 | if (TextUtils.isEmpty(token)) {
131 | intent = new Intent(AdActivity.this, LoginActivity.class);
132 | } else {
133 | intent = new Intent(AdActivity.this, MainActivity.class);
134 | MyApplication.setToken(token);
135 | }
136 | startActivity(intent);
137 | finish();
138 | }
139 |
140 |
141 |
142 |
143 | @Override
144 | public void setAdTime(int count) {
145 | initTimeCount = count + 3;
146 | }
147 |
148 | @Override
149 | public void setLoginCheckBean(LoginCheckBean loginCheckBean) {
150 | this.loginCheckBean = loginCheckBean;
151 | }
152 |
153 | @Override
154 | public void setAdImg(Bitmap bitmap) {
155 | if (bitmap != null) {
156 | ivAdvertising.setImageBitmap(bitmap);
157 | } else {//加强用户体验,如果是获取到的bitmap为null,则直接跳过
158 | continueCount = false;
159 | toNextActivity();
160 | finish();
161 | }
162 | }
163 |
164 | @Override
165 | protected void onDestroy() {
166 | super.onDestroy();
167 | if (bitmap != null) {//进行bitmap回收
168 | bitmap.recycle();
169 | }
170 | pAd.detachView();
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.zone.forgithubproject.base.BaseActivity;
6 |
7 | public class LoginActivity extends BaseActivity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.activity_login);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.zone.forgithubproject.base.BaseActivity;
6 |
7 | public class MainActivity extends BaseActivity {
8 |
9 | @Override
10 | protected void onCreate(Bundle savedInstanceState) {
11 | super.onCreate(savedInstanceState);
12 | setContentView(R.layout.activity_main);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/WebViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.os.SystemClock;
6 | import android.support.v7.widget.Toolbar;
7 | import android.text.TextUtils;
8 | import android.view.KeyEvent;
9 | import android.webkit.WebSettings;
10 | import android.webkit.WebView;
11 | import android.webkit.WebViewClient;
12 | import android.widget.Toast;
13 |
14 |
15 | import com.zone.forgithubproject.myApplication.MyApplication;
16 | import com.zone.forgithubproject.weidge.ProgressWebView;
17 | import com.zone.forgithubproject.base.BaseActivity;
18 | import com.zone.forgithubproject.utils.SPUtils;
19 |
20 | import butterknife.ButterKnife;
21 |
22 | /**
23 | * Created by john on 2016/7/18.
24 | */
25 | public class WebViewActivity extends BaseActivity {
26 |
27 |
28 | ProgressWebView wv;
29 | private long djtime[] = new long[2];
30 | private Toolbar toolbar;
31 | private String from;
32 |
33 |
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | // setTheme();
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.activity_webview);
40 | ButterKnife.inject(this);
41 | toolbar = (Toolbar) findViewById(R.id.toolbar);
42 | wv = (ProgressWebView) findViewById(R.id.wv);
43 | setSupportActionBar(toolbar);
44 | iniBase();
45 | String title = getIntent().getStringExtra("title");
46 | String url = getIntent().getStringExtra("url");
47 | from = getIntent().getStringExtra("from");
48 | toolbar.setTitle(title);
49 | wv.setWebViewClient(new WebViewClient() {//防止调用系统的浏览器
50 | @Override
51 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
52 | view.loadUrl(url);
53 | return true;
54 | }
55 | });
56 | // wv.setWebChromeClient(new WebChromeClient(){
57 | // @Override
58 | // public void onProgressChanged(WebView view, int newProgress) {
59 | // //get the newProgress and refresh progress bar
60 | // L.d("==progress==>"+String.valueOf(newProgress));
61 | // }
62 | //
63 | // @Override
64 | // public void onReceivedTitle(WebView view, String title) {
65 | // super.onReceivedTitle(view, title);
66 | // L.d("==Title==>"+title);
67 | //
68 | // }
69 | // });
70 | wv.getSettings().setDefaultTextEncodingName("utf-8");
71 | //支持js
72 | wv.getSettings().setJavaScriptEnabled(true);
73 | //设置背景颜色 透明
74 | // wv.setBackgroundColor(Color.argb(0, 0, 0, 0));
75 | WebSettings webSettings = wv.getSettings();
76 | webSettings.setSupportZoom(true);
77 | //启用数据库
78 | // webSettings.setDatabaseEnabled(true);
79 | //
80 | ////设置定位的数据库路径
81 | //
82 | // String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
83 | //
84 | // webSettings.setGeolocationDatabasePath(dir);
85 | //启用地理定位
86 | webSettings.setGeolocationEnabled(true);
87 | //开启DomStorage缓存
88 |
89 | webSettings.setDomStorageEnabled(true);
90 |
91 | // wv.setWebChromeClient(new WebChromeClient() {//有这个好像就能通过webview定位了
92 | //
93 | // @Override
94 | // public void onReceivedIcon(WebView view, Bitmap icon) {
95 | // super.onReceivedIcon(view, icon);
96 | // }
97 | //
98 | // @Override
99 | // public void onGeolocationPermissionsShowPrompt(String origin,GeolocationPermissions.Callback callback) {
100 | // callback.invoke(origin, true, false);
101 | // super.onGeolocationPermissionsShowPrompt(origin, callback);
102 | // }
103 | // });
104 | wv.loadUrl(url);
105 | }
106 |
107 | @Override
108 | public void onBackPressed() {
109 | super.onBackPressed();
110 | if (from != null && from.equals("advertising")) {
111 | Intent intent = null;
112 | String token = (String) SPUtils.get(WebViewActivity.this, "token", "");
113 | if (TextUtils.isEmpty(token)) {
114 | intent = new Intent(WebViewActivity.this, LoginActivity.class);
115 | } else {
116 | intent = new Intent(WebViewActivity.this, MainActivity.class);
117 | MyApplication.setToken(token);
118 | }
119 | startActivity(intent);
120 | finish();
121 | }
122 |
123 | }
124 |
125 | @Override
126 | public boolean onKeyDown(int keyCode, KeyEvent event) {
127 | if (from != null && from.equals("advertising")) {//判断是否来自广告页面
128 | toNextActivity();
129 | finish();
130 | return true;
131 | }
132 |
133 | if (keyCode == KeyEvent.KEYCODE_BACK && wv.canGoBack()) {
134 | wv.goBack();
135 | return true;
136 | } else {
137 | System.arraycopy(djtime, 1, djtime, 0, djtime.length - 1);
138 | djtime[djtime.length - 1] = SystemClock.uptimeMillis();
139 | if (djtime[0] >= (SystemClock.uptimeMillis() - 1000)) {
140 | finish();
141 | } else {
142 | Toast.makeText(this, "再按一次返回", Toast.LENGTH_SHORT).show();
143 | }
144 | return true;
145 | }
146 | }
147 |
148 | private void toNextActivity() {//判断去登录界面还是主界面
149 | Intent intent = null;
150 | String token = (String) SPUtils.get(WebViewActivity.this, "token", "");
151 | if (TextUtils.isEmpty(token)) {
152 | intent = new Intent(WebViewActivity.this, LoginActivity.class);
153 | } else {
154 | intent = new Intent(WebViewActivity.this, MainActivity.class);
155 | MyApplication.setToken(token);
156 | }
157 | startActivity(intent);
158 | }
159 |
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.base;
2 |
3 | import android.app.AlertDialog;
4 | import android.app.ProgressDialog;
5 | import android.content.Context;
6 | import android.content.DialogInterface;
7 | import android.os.Bundle;
8 | import android.view.LayoutInflater;
9 | import android.view.MenuItem;
10 | import android.view.View;
11 |
12 |
13 | import com.zhy.autolayout.AutoLayoutActivity;
14 | import com.zone.forgithubproject.utils.T;
15 |
16 |
17 | /**
18 | * Created by john on 2016/7/26.
19 | */
20 | public abstract class BaseActivity extends AutoLayoutActivity {
21 |
22 | private AlertDialog dialog;
23 | private ProgressDialog mProgressDialog = null;
24 |
25 | public interface Convert {
26 | void transaction(View dialogView, AlertDialog alertDialog);
27 | }
28 |
29 | public interface DialogOnClickListener {
30 | void positiveListener(DialogInterface dialog, int which);
31 |
32 | void negativeListener(DialogInterface dialog, int which);
33 | }
34 |
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 | }
40 |
41 | protected void iniBase() {
42 | getSupportActionBar().setHomeButtonEnabled(true); //设置返回键可用
43 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);//创建返回键,并实现打开关/闭监听
44 | getSupportActionBar().setDisplayShowTitleEnabled(false);//隐藏系统默认的Title
45 | }
46 |
47 | protected void backhome(MenuItem item) {
48 | switch (item.getItemId()) {
49 | case android.R.id.home:
50 | onBackPressed();
51 | break;
52 | }
53 | }
54 |
55 | public void showProgressDialog(String message) {
56 | if (mProgressDialog == null) {
57 | mProgressDialog = new ProgressDialog(this);
58 | }
59 | mProgressDialog.setMessage(message);
60 | mProgressDialog.setCanceledOnTouchOutside(false);
61 | mProgressDialog.show();
62 | }
63 |
64 |
65 | public void hideProgressDialog() {
66 | if (mProgressDialog != null) {
67 | mProgressDialog.hide();
68 | }
69 | }
70 |
71 |
72 | public void showAlertDialog(String title, String message) {
73 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
74 | builder.setTitle(title);
75 | builder.setMessage(message);
76 | builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
77 | @Override
78 | public void onClick(DialogInterface dialog, int which) {
79 |
80 | }
81 | });
82 | AlertDialog dialog = builder.create();
83 | dialog.show();
84 | }
85 |
86 |
87 |
88 | public void showToast(String message) {
89 | T.showShort(this, message);
90 | }
91 |
92 | @Override
93 | protected void onResume() {
94 | super.onResume();
95 | }
96 |
97 |
98 | @Override
99 | protected void onDestroy() {
100 | super.onDestroy();
101 | if (mProgressDialog != null) {
102 | mProgressDialog.dismiss();
103 | }
104 | }
105 |
106 | @Override
107 | protected void onPause() {
108 | super.onPause();
109 |
110 | }
111 |
112 | @Override
113 | public boolean onOptionsItemSelected(MenuItem item) {
114 | switch (item.getItemId()) {
115 | case android.R.id.home:
116 | onBackPressed();
117 | break;
118 | }
119 | return super.onOptionsItemSelected(item);
120 | }
121 |
122 | public void onBackPressed() {
123 | super.onBackPressed();
124 | finish();
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/base/BaseBean.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.base;
2 |
3 | /**
4 | * Created by john on 2016/9/8.
5 | */
6 | public class BaseBean {
7 | public String code;
8 | public String message;
9 | public T data;
10 |
11 | public boolean success() {
12 | return code.equals("200");
13 | }
14 |
15 | public boolean error404() {
16 | return code.equals("404");
17 | }
18 |
19 | @Override
20 | public String toString() {
21 | return "code=>"+code+"\nmessage=>"+message+"\ndata=>"+data;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/base/IBaseView.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.base;
2 |
3 | /**
4 | * Created by john on 2016/7/26.
5 | */
6 | public interface IBaseView {
7 | void showToast(String message);
8 | void showAlertDialog(String title, String message);
9 | void hideProgressDialog();
10 | void showProgressDialog(String message);
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/base/IPBase.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.base;
2 |
3 | /**
4 | * Created by john on 2016/9/13.
5 | */
6 | public interface IPBase {
7 | void attachView(V view);
8 | void detachView();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/base/PBase.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.base;
2 |
3 | import com.zone.forgithubproject.utils.L;
4 |
5 |
6 | /**
7 | * Created by zone on 2016/9/13.
8 | */
9 | public class PBase implements IPBase {
10 | public V view;
11 |
12 | @Override
13 | public void attachView(V view) {
14 | this.view = view;
15 | }
16 |
17 | @Override
18 | public void detachView() {
19 | this.view = null;
20 | }
21 |
22 | public boolean isAttachView() {
23 | return view != null;
24 | }
25 |
26 | public V getMyView() {
27 | return view;
28 | }
29 |
30 | public void checkAttachView() {
31 | if (!isAttachView()) {
32 | L.d("====>View没有连接!!!");
33 | }
34 | }
35 |
36 |
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/contract/AdContract.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.contract;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | import com.zone.forgithubproject.base.IBaseView;
6 | import com.zone.forgithubproject.model.bean.LoginCheckBean;
7 |
8 | /**
9 | * Created by zone on 2017/3/26.
10 | */
11 |
12 | public class AdContract {
13 | public interface View extends IBaseView{
14 | void setAdTime(int count);
15 |
16 | void setLoginCheckBean(LoginCheckBean loginCheckBean);
17 |
18 | void setAdImg(Bitmap bitmap);
19 | }
20 |
21 | public interface Presenter {
22 | }
23 |
24 | public interface Model{
25 | }
26 |
27 |
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/contract/LoginContract.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.contract;
2 |
3 | /**
4 | * Created by zone on 2017/3/26.
5 | */
6 |
7 | public class LoginContract {
8 | public interface View{
9 |
10 | }
11 |
12 | public interface Presenter{
13 |
14 | }
15 |
16 | public interface Model{
17 |
18 | }
19 |
20 |
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/contract/MainContract.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.contract;
2 |
3 | /**
4 | * Created by zone on 2017/3/26.
5 | */
6 |
7 | public class MainContract {
8 |
9 | public interface View{
10 | }
11 |
12 | public interface Presenter{
13 | }
14 |
15 | public interface Model{
16 | }
17 |
18 |
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/model/AdModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.model;
2 |
3 | import com.zone.forgithubproject.contract.AdContract;
4 | import com.zone.forgithubproject.model.bean.AdMessageBean;
5 | import com.zone.forgithubproject.model.bean.LoginCheckBean;
6 | import com.zone.forgithubproject.service.RetrofitService;
7 | import com.zone.forgithubproject.service.RetrofitServiceInstance;
8 |
9 | import okhttp3.ResponseBody;
10 | import rx.Observable;
11 | import rx.Subscriber;
12 |
13 | /**
14 | * Created by zone on 2017/03/26
15 | */
16 |
17 | public class AdModelImpl implements AdContract.Model {
18 | RetrofitService retrofitService;
19 | public AdModelImpl() {
20 | retrofitService = RetrofitServiceInstance.getInstance();
21 | }
22 | public Observable getLoginCheck() {//假装服务器要展示广告
23 | return Observable.create(new Observable.OnSubscribe() {
24 | @Override
25 | public void call(Subscriber super LoginCheckBean> subscriber) {
26 | subscriber.onNext(new LoginCheckBean(true));
27 | subscriber.onCompleted();
28 | }
29 | });
30 | }
31 |
32 | public Observable getAdMessage() {
33 | return Observable.create(new Observable.OnSubscribe() {
34 | @Override
35 | public void call(Subscriber super AdMessageBean> subscriber) {//假装要展示 3 秒广告,且广告图为如下图
36 | subscriber.onNext(new AdMessageBean(3,"http://odjfpxwey.bkt.clouddn.com/2017-3-3-20-141110180-Screenshot_2017-02-23-23-10-26-062_com.tmall.wireless.png","http://www.baidu.com"));
37 | subscriber.onCompleted();
38 | }
39 | });
40 | }
41 |
42 | public Observable downLoadFile(String fileUrl) {
43 | return retrofitService.downLoadFile(fileUrl);
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/model/LoginModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.model;
2 | import com.zone.forgithubproject.contract.LoginContract;
3 |
4 | /**
5 | * Created by john on 2017/03/26
6 | */
7 |
8 | public class LoginModelImpl implements LoginContract.Model{
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/model/MainModelImpl.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.model;
2 | import com.zone.forgithubproject.contract.MainContract;
3 |
4 | /**
5 | * Created by john on 2017/03/26
6 | */
7 |
8 | public class MainModelImpl implements MainContract.Model{
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/model/bean/AdMessageBean.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.model.bean;
2 |
3 | /**
4 | * Created by john on 2016/12/30.
5 | */
6 | public class AdMessageBean {
7 | int adTime;//播放广告的时常
8 | String adPictureUrl;//广告图片的地址
9 | String adUrl;//点击广告图片时,展示详情 webview 的地址
10 |
11 | public AdMessageBean(int adTime, String adPictureUrl, String adUrl) {
12 | this.adTime = adTime;
13 | this.adPictureUrl = adPictureUrl;
14 | this.adUrl = adUrl;
15 | }
16 |
17 | public int getAdTime() {
18 | return adTime;
19 | }
20 |
21 | public void setAdTime(int adTime) {
22 | this.adTime = adTime;
23 | }
24 |
25 | public String getAdPictureUrl() {
26 | return adPictureUrl;
27 | }
28 |
29 | public void setAdPictureUrl(String adPictureUrl) {
30 | this.adPictureUrl = adPictureUrl;
31 | }
32 |
33 | public String getAdUrl() {
34 | return adUrl;
35 | }
36 |
37 | public void setAdUrl(String adUrl) {
38 | this.adUrl = adUrl;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/model/bean/LoginCheckBean.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.model.bean;
2 |
3 | /**
4 | * Created by john on 2016/12/30.
5 | */
6 | public class LoginCheckBean {
7 | private boolean isPlayAd = false;//默认赋值 false ,当没有网络时,也不会 NullPoint
8 |
9 | public LoginCheckBean(boolean isPlayAd) {
10 | this.isPlayAd = isPlayAd;
11 | }
12 | public LoginCheckBean() {
13 | }
14 |
15 |
16 | public boolean isPlayAd() {
17 | return isPlayAd;
18 | }
19 |
20 | public void setPlayAd(boolean playAd) {
21 | isPlayAd = playAd;
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/myApplication/MyApplication.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.myApplication;
2 |
3 | import android.app.Application;
4 |
5 | /**
6 | * Created by john on 2016/5/8.
7 | */
8 | public class MyApplication extends Application {
9 | public static String getToken() {
10 | return token;
11 | }
12 |
13 | public static void setToken(String token) {
14 | MyApplication.token = token;
15 | }
16 |
17 | private static String token = "";
18 |
19 |
20 |
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 |
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/presenter/LoginPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.presenter;
2 | import com.zone.forgithubproject.contract.LoginContract;
3 |
4 | /**
5 | * Created by john on 2017/03/26
6 | */
7 |
8 | public class LoginPresenterImpl implements LoginContract.Presenter{
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/presenter/MainPresenterImpl.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.presenter;
2 | import com.zone.forgithubproject.contract.MainContract;
3 |
4 | /**
5 | * Created by john on 2017/03/26
6 | */
7 |
8 | public class MainPresenterImpl implements MainContract.Presenter{
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/service/RetrofitService.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.service;
2 |
3 | import okhttp3.ResponseBody;
4 | import retrofit2.http.GET;
5 | import retrofit2.http.POST;
6 | import retrofit2.http.Url;
7 | import rx.Observable;
8 |
9 | /**
10 | * Created by john on 2016/9/7.
11 | */
12 | public interface RetrofitService {
13 | @GET
14 | Observable downLoadFile(@Url String fileUrl);
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/service/RetrofitServiceInstance.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.service;
2 |
3 |
4 | import android.content.Context;
5 | import android.text.TextUtils;
6 | import com.zone.forgithubproject.myApplication.MyApplication;
7 | import com.zone.forgithubproject.utils.L;
8 | import java.io.IOException;
9 | import java.util.concurrent.TimeUnit;
10 | import okhttp3.Authenticator;
11 | import okhttp3.Interceptor;
12 | import okhttp3.OkHttpClient;
13 | import okhttp3.Request;
14 | import okhttp3.Response;
15 | import okhttp3.Route;
16 | import okhttp3.logging.HttpLoggingInterceptor;
17 | import retrofit2.Retrofit;
18 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
19 | import retrofit2.converter.gson.GsonConverterFactory;
20 |
21 |
22 | /**
23 | * Created by john on 2016/9/10.
24 | */
25 | public class RetrofitServiceInstance {
26 | private static RetrofitService instance = null;
27 | public static RetrofitService getInstance() {
28 |
29 | Authenticator authenticator = new Authenticator() {//当服务器返回的状态码为401时,会自动执行里面的代码,也就实现了自动刷新token
30 | @Override
31 | public Request authenticate(Route route, Response response) throws IOException {
32 | L.d("==========> 重新刷新了token");
33 | return response.request().newBuilder()
34 | .addHeader("token","")
35 | .build();
36 | }
37 | };
38 | Interceptor tokenInterceptor = new Interceptor() {//全局拦截器,往请求头部添加token字段,就实现了全局token
39 | @Override
40 | public Response intercept(Chain chain) throws IOException {
41 | Request originalRequest = chain.request();
42 | Request tokenRequest = null;
43 | MyApplication application = new MyApplication();
44 | if (TextUtils.isEmpty(MyApplication.getToken())) {
45 | L.d("MyApplication 的token值为空!!!!!!!!!!!!!");
46 | return chain.proceed(originalRequest);
47 | }
48 | tokenRequest = originalRequest.newBuilder()
49 | .header("token",MyApplication.getToken())
50 | .build();
51 |
52 | return chain.proceed(tokenRequest);
53 | }
54 | };
55 | HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {//log拦截器,打印所有的log
56 | @Override
57 | public void log(String message) {
58 | L.d(message);
59 | }
60 | });
61 | OkHttpClient client = new OkHttpClient.Builder()
62 | .connectTimeout(15, TimeUnit.SECONDS)
63 | .retryOnConnectionFailure(true)
64 | .addNetworkInterceptor(tokenInterceptor)
65 | .addInterceptor(loggingInterceptor)
66 | .authenticator(authenticator)
67 | .build();
68 | if (instance == null) {
69 | synchronized (RetrofitService.class) {
70 | if (instance == null) {
71 | Retrofit retrofit = new Retrofit.Builder() //生成实例
72 | .baseUrl("http://115.159.212.89:3000/") //基础url,会拼接NetService中的参数
73 | .client(client)
74 | .addConverterFactory(GsonConverterFactory.create()) //使用Gson解析
75 | .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //加入RxJava的适配器
76 | .build();
77 |
78 | instance = retrofit.create(RetrofitService.class);
79 | }
80 | }
81 | }
82 | return instance;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/utils/L.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.utils;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by john on 2016/7/25.
7 | */
8 | public class L {
9 | private L()
10 | {
11 | /* cannot be instantiated */
12 | throw new UnsupportedOperationException("cannot be instantiated");
13 | }
14 |
15 | public static boolean isDebug = true;// 是否需要打印bug,可以在application的onCreate函数里面初始化
16 | private static final String TAG = "zoneLog";
17 |
18 | // 下面四个是默认tag的函数
19 | public static void i(String msg)
20 | {
21 | if (!isDebug) return;
22 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
23 | Log.i(TAG, "(" + targetStackTraceElement.getFileName() + ":"
24 | + targetStackTraceElement.getLineNumber() + ")");
25 | Log.i(TAG, msg);
26 | }
27 |
28 | public static void d(String msg)
29 | {
30 | if (!isDebug) return;
31 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
32 | Log.d(TAG, "(" + targetStackTraceElement.getFileName() + ":"
33 | + targetStackTraceElement.getLineNumber() + ")");
34 | Log.d(TAG, msg);
35 | }
36 |
37 | public static void e(String msg)
38 | {
39 | if (!isDebug) return;
40 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
41 | Log.e(TAG, "(" + targetStackTraceElement.getFileName() + ":"
42 | + targetStackTraceElement.getLineNumber() + ")");
43 | Log.e(TAG, msg);
44 | }
45 |
46 | public static void v(String msg)
47 | {
48 | if (!isDebug) return;
49 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
50 | Log.v(TAG, "(" + targetStackTraceElement.getFileName() + ":"
51 | + targetStackTraceElement.getLineNumber() + ")");
52 | Log.v(TAG, msg);
53 | }
54 |
55 | // 下面是传入自定义tag的函数
56 | public static void i(String tag, String msg)
57 | {
58 | if (!isDebug) return;
59 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
60 | Log.i(tag, "(" + targetStackTraceElement.getFileName() + ":"
61 | + targetStackTraceElement.getLineNumber() + ")");
62 | Log.i(tag, msg);
63 | }
64 |
65 | public static void d(String tag, String msg)
66 | {
67 | if (!isDebug) return;
68 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
69 | Log.d(tag, "(" + targetStackTraceElement.getFileName() + ":"
70 | + targetStackTraceElement.getLineNumber() + ")");
71 | Log.d(tag, msg);
72 | }
73 |
74 | public static void e(String tag, String msg)
75 | {
76 | if (!isDebug) return;
77 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
78 | Log.e(tag, "(" + targetStackTraceElement.getFileName() + ":"
79 | + targetStackTraceElement.getLineNumber() + ")");
80 | Log.e(tag, msg);
81 | }
82 |
83 | public static void v(String tag, String msg)
84 | {
85 | if (!isDebug) return;
86 | StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
87 | Log.v(tag, "(" + targetStackTraceElement.getFileName() + ":"
88 | + targetStackTraceElement.getLineNumber() + ")");
89 | Log.v(tag, msg);
90 | }
91 |
92 | private static StackTraceElement getTargetStackTraceElement() {
93 | // find the target invoked method
94 | StackTraceElement targetStackTrace = null;
95 | boolean shouldTrace = false;
96 | StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
97 | for (StackTraceElement stackTraceElement : stackTrace) {
98 | boolean isLogMethod = stackTraceElement.getClassName().equals(L.class.getName());
99 | if (shouldTrace && !isLogMethod) {
100 | targetStackTrace = stackTraceElement;
101 | break;
102 | }
103 | shouldTrace = isLogMethod;
104 | }
105 | return targetStackTrace;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/utils/NetUtils.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.utils;
2 |
3 | /**
4 | * Created by john on 2016/7/25.
5 | */
6 | import android.app.Activity;
7 | import android.content.ComponentName;
8 | import android.content.Context;
9 | import android.content.Intent;
10 | import android.net.ConnectivityManager;
11 | import android.net.NetworkInfo;
12 |
13 | /**
14 | * 跟网络相关的工具类
15 | *
16 | *
17 | *
18 | */
19 | public class NetUtils
20 | {
21 | private NetUtils()
22 | {
23 | /* cannot be instantiated */
24 | throw new UnsupportedOperationException("cannot be instantiated");
25 | }
26 |
27 | /**
28 | * 判断网络是否连接
29 | *
30 | * @param context
31 | * @return
32 | */
33 | public static boolean isConnected(Context context)
34 | {
35 | if (context == null) {
36 | L.d("传进来的context实例为空!");
37 | }
38 | ConnectivityManager connectivity = (ConnectivityManager) context
39 | .getSystemService(Context.CONNECTIVITY_SERVICE);
40 |
41 | if (null != connectivity)
42 | {
43 |
44 | NetworkInfo info = connectivity.getActiveNetworkInfo();
45 | if (null != info && info.isConnected())
46 | {
47 | if (info.getState() == NetworkInfo.State.CONNECTED)
48 | {
49 | return true;
50 | }
51 | }
52 | }
53 | return false;
54 | }
55 |
56 | /**
57 | * 判断是否是wifi连接
58 | */
59 | public static boolean isWifi(Context context)
60 | {
61 | ConnectivityManager cm = (ConnectivityManager) context
62 | .getSystemService(Context.CONNECTIVITY_SERVICE);
63 |
64 | if (cm == null)
65 | return false;
66 | return cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
67 |
68 | }
69 |
70 | /**
71 | * 打开网络设置界面
72 | */
73 | public static void openSetting(Activity activity)
74 | {
75 | Intent intent = new Intent("/");
76 | ComponentName cm = new ComponentName("com.android.settings",
77 | "com.android.settings.WirelessSettings");
78 | intent.setComponent(cm);
79 | intent.setAction("android.intent.action.VIEW");
80 | activity.startActivityForResult(intent, 0);
81 | }
82 |
83 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/utils/Rx/RxHelper.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.utils.Rx;
2 |
3 | import com.zone.forgithubproject.base.BaseBean;
4 | import com.zone.forgithubproject.utils.L;
5 | import rx.Observable;
6 | import rx.Subscriber;
7 | import rx.android.schedulers.AndroidSchedulers;
8 | import rx.functions.Func1;
9 | import rx.schedulers.Schedulers;
10 |
11 | /**
12 | * Created by john on 2016/9/8.
13 | */
14 | public class RxHelper {
15 |
16 | public static Observable.Transformer, T> handleResult() {
17 | return new Observable.Transformer, T>() {
18 | @Override
19 | public Observable call(Observable> baseBeanObservable) {
20 | return baseBeanObservable.flatMap(new Func1, Observable>() {
21 | @Override
22 | public Observable call(BaseBean result) {
23 | if (result.success()) {//判断返回的code是否为200,如果是则取到结果往下传
24 | L.d("====>code==200");
25 | L.d("====>message=="+result.message);
26 | return createData(result.data);
27 | // return Observable.concat().first();
28 | } else {
29 | L.d("====code==>"+result.code);
30 | // return Observable.error(new Exception(result.message));
31 | return createError(result.message);
32 | }
33 | }
34 | }).subscribeOn(Schedulers.io())
35 | .observeOn(AndroidSchedulers.mainThread());
36 | }
37 | };
38 | }
39 |
40 |
41 |
42 |
43 | private static Observable createData(final T data) {
44 | return Observable.create(new Observable.OnSubscribe() {
45 | @Override
46 | public void call(Subscriber super T> subscriber) {
47 | try {
48 | subscriber.onNext(data);
49 | subscriber.onCompleted();
50 | } catch (Exception e) {
51 | e.printStackTrace();
52 | subscriber.onError(e);
53 | }
54 | }
55 | });
56 | }
57 | private static Observable createError(final String data) {
58 | return Observable.create(new Observable.OnSubscribe() {
59 | @Override
60 | public void call(Subscriber super String> subscriber) {
61 | try {
62 | subscriber.onError(new Exception(data));
63 | subscriber.onCompleted();
64 | } catch (Exception e) {
65 | e.printStackTrace();
66 | subscriber.onError(e);
67 | }
68 | }
69 | });
70 | }
71 | private static Observable createData2(final T data) {
72 | return Observable.create(new Observable.OnSubscribe() {
73 | @Override
74 | public void call(Subscriber super T> subscriber) {
75 | try {
76 | subscriber.onNext(data);
77 | subscriber.onCompleted();
78 | } catch (Exception e) {
79 | e.printStackTrace();
80 | subscriber.onError(e);
81 | }
82 | }
83 | });
84 | }
85 | }
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/utils/Rx/RxSubscribe.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.utils.Rx;
2 |
3 | import android.content.Context;
4 | import com.zone.forgithubproject.utils.L;
5 | import com.zone.forgithubproject.utils.NetUtils;
6 | import rx.Subscriber;
7 |
8 | /**
9 | * Created by john on 2016/9/8.
10 | */
11 | public abstract class RxSubscribe extends Subscriber {
12 | private Context mContext;
13 |
14 | public RxSubscribe(Context context) {
15 | mContext = context;
16 | }
17 | public RxSubscribe() {}
18 |
19 |
20 |
21 | protected abstract void _onNext(T t);
22 |
23 | protected abstract void _onError(String message);
24 |
25 |
26 |
27 | @Override
28 | public void onNext(T t) {
29 | _onNext(t);
30 | }
31 |
32 | @Override
33 | public void onError(Throwable e) {
34 | e.printStackTrace();
35 |
36 | try {
37 | if (!NetUtils.isConnected(mContext)) {
38 | L.d("RxSubscribe====>网络不可用!zone");
39 | _onError("网络错误,请检查网络!");
40 | }
41 | } catch (Exception e1) {
42 | e1.printStackTrace();
43 | }
44 | _onError(e.getMessage());
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/utils/SPUtils.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.utils;
2 |
3 | /**
4 | * Created by john on 2016/7/25.
5 | */
6 |
7 | import android.content.Context;
8 | import android.content.SharedPreferences;
9 |
10 | import java.lang.reflect.InvocationTargetException;
11 | import java.lang.reflect.Method;
12 | import java.util.Map;
13 |
14 | public class SPUtils
15 | {
16 | /**
17 | * 保存在手机里面的文件名
18 | */
19 | public static final String FILE_NAME = "share_data";
20 |
21 | /**
22 | * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
23 | *
24 | * @param context
25 | * @param key
26 | * @param object
27 | */
28 | public static void put(Context context, String key, Object object)
29 | {
30 |
31 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
32 | Context.MODE_PRIVATE);
33 | SharedPreferences.Editor editor = sp.edit();
34 |
35 | if (object instanceof String)
36 | {
37 | editor.putString(key, (String) object);
38 | } else if (object instanceof Integer)
39 | {
40 | editor.putInt(key, (Integer) object);
41 | } else if (object instanceof Boolean)
42 | {
43 | editor.putBoolean(key, (Boolean) object);
44 | } else if (object instanceof Float)
45 | {
46 | editor.putFloat(key, (Float) object);
47 | } else if (object instanceof Long)
48 | {
49 | editor.putLong(key, (Long) object);
50 | } else
51 | {
52 | editor.putString(key, object.toString());
53 | }
54 |
55 | SharedPreferencesCompat.apply(editor);
56 | }
57 |
58 | /**
59 | * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
60 | *
61 | * @param context
62 | * @param key
63 | * @param defaultObject
64 | * @return
65 | */
66 | public static Object get(Context context, String key, Object defaultObject)
67 | {
68 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
69 | Context.MODE_PRIVATE);
70 |
71 | if (defaultObject instanceof String)
72 | {
73 | return sp.getString(key, (String) defaultObject);
74 | } else if (defaultObject instanceof Integer)
75 | {
76 | return sp.getInt(key, (Integer) defaultObject);
77 | } else if (defaultObject instanceof Boolean)
78 | {
79 | return sp.getBoolean(key, (Boolean) defaultObject);
80 | } else if (defaultObject instanceof Float)
81 | {
82 | return sp.getFloat(key, (Float) defaultObject);
83 | } else if (defaultObject instanceof Long)
84 | {
85 | return sp.getLong(key, (Long) defaultObject);
86 | }
87 |
88 | return null;
89 | }
90 |
91 | /**
92 | * 移除某个key值已经对应的值
93 | * @param context
94 | * @param key
95 | */
96 | public static void remove(Context context, String key)
97 | {
98 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
99 | Context.MODE_PRIVATE);
100 | SharedPreferences.Editor editor = sp.edit();
101 | editor.remove(key);
102 | SharedPreferencesCompat.apply(editor);
103 | }
104 |
105 | /**
106 | * 清除所有数据
107 | * @param context
108 | */
109 | public static void clear(Context context)
110 | {
111 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
112 | Context.MODE_PRIVATE);
113 | SharedPreferences.Editor editor = sp.edit();
114 | editor.clear();
115 | SharedPreferencesCompat.apply(editor);
116 | }
117 |
118 | /**
119 | * 查询某个key是否已经存在
120 | * @param context
121 | * @param key
122 | * @return
123 | */
124 | public static boolean contains(Context context, String key)
125 | {
126 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
127 | Context.MODE_PRIVATE);
128 | return sp.contains(key);
129 | }
130 |
131 | /**
132 | * 返回所有的键值对
133 | *
134 | * @param context
135 | * @return
136 | */
137 | public static Map getAll(Context context)
138 | {
139 | SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
140 | Context.MODE_PRIVATE);
141 | return sp.getAll();
142 | }
143 |
144 | /**
145 | * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
146 | *
147 | * @author zhy
148 | *
149 | */
150 | private static class SharedPreferencesCompat
151 | {
152 | private static final Method sApplyMethod = findApplyMethod();
153 |
154 | /**
155 | * 反射查找apply的方法
156 | *
157 | * @return
158 | */
159 | @SuppressWarnings({ "unchecked", "rawtypes" })
160 | private static Method findApplyMethod()
161 | {
162 | try
163 | {
164 | Class clz = SharedPreferences.Editor.class;
165 | return clz.getMethod("apply");
166 | } catch (NoSuchMethodException e)
167 | {
168 | }
169 |
170 | return null;
171 | }
172 |
173 | /**
174 | * 如果找到则使用apply执行,否则使用commit
175 | *
176 | * @param editor
177 | */
178 | public static void apply(SharedPreferences.Editor editor)
179 | {
180 | try
181 | {
182 | if (sApplyMethod != null)
183 | {
184 | sApplyMethod.invoke(editor);
185 | return;
186 | }
187 | } catch (IllegalArgumentException e)
188 | {
189 | } catch (IllegalAccessException e)
190 | {
191 | } catch (InvocationTargetException e)
192 | {
193 | }
194 | editor.commit();
195 | }
196 | }
197 |
198 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/utils/T.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.utils;
2 |
3 | /**
4 | * Created by john on 2016/7/25.
5 | */
6 | import android.content.Context;
7 | import android.support.design.widget.Snackbar;
8 | import android.view.View;
9 | import android.widget.Toast;
10 |
11 | /**
12 | * Toast统一管理类
13 | *
14 | */
15 | public class T
16 | {
17 |
18 | private T()
19 | {
20 | /* cannot be instantiated */
21 | throw new UnsupportedOperationException("cannot be instantiated");
22 | }
23 |
24 | public static boolean isShow = true;
25 |
26 |
27 | public static void showShortSnackBar(View view,String message) {
28 | Snackbar.make(view,message,Snackbar.LENGTH_SHORT).show();
29 | }
30 | public static void showLongSnackBar(View view,String message) {
31 | Snackbar.make(view,message,Snackbar.LENGTH_LONG).show();
32 | }
33 |
34 | /**
35 | * 短时间显示Toast
36 | *
37 | * @param context
38 | * @param message
39 | */
40 | public static void showShort(Context context, CharSequence message)
41 | {
42 | if (isShow)
43 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
44 | }
45 |
46 | /**
47 | * 短时间显示Toast
48 | *
49 | * @param context
50 | * @param message
51 | */
52 | public static void showShort(Context context, int message)
53 | {
54 | if (isShow)
55 | Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
56 | }
57 |
58 | /**
59 | * 长时间显示Toast
60 | *
61 | * @param context
62 | * @param message
63 | */
64 | public static void showLong(Context context, CharSequence message)
65 | {
66 | if (isShow)
67 | Toast.makeText(context, message, Toast.LENGTH_LONG).show();
68 | }
69 |
70 | /**
71 | * 长时间显示Toast
72 | *
73 | * @param context
74 | * @param message
75 | */
76 | public static void showLong(Context context, int message)
77 | {
78 | if (isShow)
79 | Toast.makeText(context, message, Toast.LENGTH_LONG).show();
80 | }
81 |
82 | /**
83 | * 自定义显示Toast时间
84 | *
85 | * @param context
86 | * @param message
87 | * @param duration
88 | */
89 | public static void show(Context context, CharSequence message, int duration)
90 | {
91 | if (isShow)
92 | Toast.makeText(context, message, duration).show();
93 | }
94 |
95 | /**
96 | * 自定义显示Toast时间
97 | *
98 | * @param context
99 | * @param message
100 | * @param duration
101 | */
102 | public static void show(Context context, int message, int duration)
103 | {
104 | if (isShow)
105 | Toast.makeText(context, message, duration).show();
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zone/forgithubproject/weidge/ProgressWebView.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject.weidge;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.util.AttributeSet;
6 | import android.webkit.GeolocationPermissions;
7 | import android.webkit.WebView;
8 | import android.widget.ProgressBar;
9 |
10 | import com.zone.forgithubproject.utils.L;
11 |
12 | /**
13 | * Created by john on 2016/11/3.
14 | */
15 | @SuppressWarnings("deprecation")
16 | public class ProgressWebView extends WebView {
17 |
18 | private ProgressBar progressbar;
19 |
20 | public ProgressWebView(Context context, AttributeSet attrs) {
21 | super(context, attrs);
22 | progressbar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
23 | progressbar.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 12, 0, 0));
24 | // progressbar.setBackgroundColor(getResources().getColor(R.color.colorBlackFont));
25 | // progressbar.setDrawingCacheBackgroundColor(getResources().getColor(R.color.colorBlackFont));
26 | addView(progressbar);
27 | // setWebViewClient(new WebViewClient(){});
28 | setWebChromeClient(new WebChromeClient());
29 | }
30 |
31 | public class WebChromeClient extends android.webkit.WebChromeClient {
32 | @Override
33 | public void onReceivedIcon(WebView view, Bitmap icon) {
34 |
35 | super.onReceivedIcon(view, icon);
36 |
37 | }
38 |
39 | @Override
40 | public void onGeolocationPermissionsShowPrompt(String origin,GeolocationPermissions.Callback callback) {
41 | callback.invoke(origin, true, false);
42 | super.onGeolocationPermissionsShowPrompt(origin, callback);
43 | }
44 | @Override
45 | public void onProgressChanged(WebView view, int newProgress) {
46 | if (newProgress == 100) {
47 | progressbar.setVisibility(GONE);
48 | } else {
49 | if (progressbar.getVisibility() == GONE)
50 | progressbar.setVisibility(VISIBLE);
51 | progressbar.setProgress(newProgress);
52 | L.d("====>"+String.valueOf(newProgress));
53 | }
54 | super.onProgressChanged(view, newProgress);
55 | }
56 | }
57 |
58 | @Override
59 | protected void onScrollChanged(int l, int t, int oldl, int oldt) {
60 | LayoutParams lp = (LayoutParams) progressbar.getLayoutParams();
61 | lp.x = l;
62 | lp.y = t;
63 | progressbar.setLayoutParams(lp);
64 | super.onScrollChanged(l, t, oldl, oldt);
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/jyz_png.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/src/main/res/drawable/jyz_png.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash_jyz.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/src/main/res/drawable/splash_jyz.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/splash_skip.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_ad.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
25 |
26 |
37 |
38 |
47 |
48 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/head.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/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 |
4 | #f7f7f7
5 | #12b6f4
6 | #000000
7 |
8 | #FF4081
9 |
10 |
11 |
12 | #ecf0f3
13 | #f5f5f9
14 | #f5f5f5
15 | #f3f6f8
16 | #f7f7f7
17 | #fcfcfc
18 | #d7d7d7
19 | #ff3e3e
20 | #353535
21 | #f5f5f9
22 | #f0f0f4
23 |
24 | #999999
25 | #333333
26 | #11aff1
27 | #ffffff
28 | #000000
29 | #47c11d
30 | #3cb2ff
31 | #12b7f5
32 | #9612b7f5
33 | #393a3f
34 |
35 | #dddddd
36 | #c3c3c3
37 | #00ff15
38 |
39 |
40 |
41 | #95EE6B
42 | #5FD3B3
43 | #FFA573
44 | #F66F89
45 |
46 | #FFCD73
47 | #FFE073
48 | #FFB473
49 | #FFD540
50 |
51 | #81c2d6
52 | #8192d6
53 | #d9b3e6
54 | #dcf7a1
55 | #7BD7FA
56 | #83fcec
57 |
58 | #bfbfbf
59 | #373b3e
60 | #323639
61 | #f8f8f8
62 |
63 | #a5acad
64 | #f4f9f9
65 | #72899c
66 | #385772
67 |
68 | #81cff9
69 | #adbeff
70 | #c3b5f6
71 | #d5aef6
72 | #e6a6f5
73 | #72899c
74 | #72899c
75 | #72899c
76 | #72899c
77 | #72899c
78 | #72899c
79 | #72899c
80 |
81 |
82 |
83 | #ffbe77
84 | #e4ebee
85 | #f4f9f9
86 |
87 | #eeeeee
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ForGitHubProject
3 |
4 |
--------------------------------------------------------------------------------
/app/src/test/java/com/zone/forgithubproject/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.zone.forgithubproject;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/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.2.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | classpath 'com.antfortune.freeline:gradle:0.8.7'
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | }
20 | }
21 |
22 | task clean(type: Delete) {
23 | delete rootProject.buildDir
24 | }
25 |
--------------------------------------------------------------------------------
/freeline.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding:utf-8 -*-
3 | from __future__ import print_function
4 | import sys
5 | from argparse import ArgumentParser
6 |
7 | from freeline_core.dispatcher import Dispatcher
8 | from freeline_core.init import init
9 |
10 |
11 | class Freeline(object):
12 | def __init__(self):
13 | self.dispatcher = Dispatcher()
14 |
15 | def call(self, args=None):
16 | if 'init' in args and args.init:
17 | print('init freeline project...')
18 | init()
19 | exit()
20 |
21 | self.dispatcher.call_command(args)
22 |
23 |
24 | def get_parser():
25 | parser = ArgumentParser()
26 | parser.add_argument('-v', '--version', action='store_true', help='show version')
27 | parser.add_argument('-f', '--cleanBuild', action='store_true', help='force to execute a clean build')
28 | parser.add_argument('-w', '--wait', action='store_true', help='make application wait for debugger')
29 | parser.add_argument('-a', '--all', action='store_true',
30 | help="together with '-f', freeline will force to clean build all projects.")
31 | parser.add_argument('-c', '--clean', action='store_true', help='clean cache directory and workspace')
32 | parser.add_argument('-d', '--debug', action='store_true', help='show freeline debug output (NOT DEBUG APPLICATION)')
33 | # parser.add_argument('-i', '--init', action='store_true', help='init freeline project')
34 | parser.parse_args()
35 | return parser
36 |
37 |
38 | def main():
39 | if sys.version_info > (3, 0):
40 | print('Freeline only support Python 2.7+ now. Please use the correct version of Python for freeline.')
41 | exit()
42 |
43 | parser = get_parser()
44 | args = parser.parse_args()
45 | freeline = Freeline()
46 | freeline.call(args=args)
47 |
48 |
49 | if __name__ == '__main__':
50 | main()
51 |
--------------------------------------------------------------------------------
/freeline/freeline.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding:utf-8 -*-
3 | from __future__ import print_function
4 | import sys
5 | from argparse import ArgumentParser
6 |
7 | from freeline_core.dispatcher import Dispatcher
8 | from freeline_core.init import init
9 |
10 |
11 | class Freeline(object):
12 | def __init__(self):
13 | self.dispatcher = Dispatcher()
14 |
15 | def call(self, args=None):
16 | if 'init' in args and args.init:
17 | print('init freeline project...')
18 | init()
19 | exit()
20 |
21 | self.dispatcher.call_command(args)
22 |
23 |
24 | def get_parser():
25 | parser = ArgumentParser()
26 | parser.add_argument('-v', '--version', action='store_true', help='show version')
27 | parser.add_argument('-f', '--cleanBuild', action='store_true', help='force to execute a clean build')
28 | parser.add_argument('-w', '--wait', action='store_true', help='make application wait for debugger')
29 | parser.add_argument('-a', '--all', action='store_true',
30 | help="together with '-f', freeline will force to clean build all projects.")
31 | parser.add_argument('-c', '--clean', action='store_true', help='clean cache directory and workspace')
32 | parser.add_argument('-d', '--debug', action='store_true', help='show freeline debug output (NOT DEBUG APPLICATION)')
33 | # parser.add_argument('-i', '--init', action='store_true', help='init freeline project')
34 | parser.parse_args()
35 | return parser
36 |
37 |
38 | def main():
39 | if sys.version_info > (3, 0):
40 | print('Freeline only support Python 2.7+ now. Please use the correct version of Python for freeline.')
41 | exit()
42 |
43 | parser = get_parser()
44 | args = parser.parse_args()
45 | freeline = Freeline()
46 | freeline.call(args=args)
47 |
48 |
49 | if __name__ == '__main__':
50 | main()
51 |
--------------------------------------------------------------------------------
/freeline/freeline_core/.idea/dictionaries/huangyong.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/freeline/freeline_core/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/freeline/freeline_core/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/freeline/freeline_core/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/freeline/freeline_core/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/freeline/freeline_core/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/freeline/freeline_core/__init__.py:
--------------------------------------------------------------------------------
1 | import build_commands
2 | import builder
3 | import command
4 | import dispatcher
5 | import exceptions
6 | import task
7 | import tracing
8 | import utils
9 |
--------------------------------------------------------------------------------
/freeline/freeline_core/build_commands.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from command import AbstractBuildCommand, MacroCommand
3 |
4 |
5 | class CleanBuildCommand(AbstractBuildCommand):
6 | def __init__(self, builder):
7 | AbstractBuildCommand.__init__(self, builder, command_name='clean_build')
8 | self._setup()
9 |
10 | def execute(self):
11 | map(lambda command: command.execute(), self.command_list)
12 |
13 | def _setup(self):
14 | self.add_command(CheckBulidEnvironmentCommand(self._builder))
15 | self.add_command(FindDependenciesOfTasksCommand(self._builder))
16 | self.add_command(GenerateSortedBuildTasksCommand(self._builder))
17 | self.add_command(UpdateApkCreatedTimeCommand(self._builder))
18 | self.add_command(ExecuteCleanBuildCommand(self._builder))
19 |
20 |
21 | class IncrementalBuildCommand(AbstractBuildCommand):
22 | def __init__(self, builder):
23 | AbstractBuildCommand.__init__(self, builder, command_name='incremental_build')
24 | self._setup()
25 |
26 | def execute(self):
27 | map(lambda command: command.execute(), self.command_list)
28 |
29 | def _setup(self):
30 | self.add_command(CheckBulidEnvironmentCommand(self._builder))
31 | self.add_command(GenerateSortedBuildTasksCommand(self._builder))
32 | self.add_command(ExecuteIncrementalBuildCommand(self._builder))
33 |
34 |
35 | class CheckBulidEnvironmentCommand(AbstractBuildCommand):
36 | def __init__(self, builder):
37 | AbstractBuildCommand.__init__(self, builder, command_name='check_build_environment')
38 |
39 | def execute(self):
40 | self._builder.check_build_environment()
41 |
42 |
43 | class FindDependenciesOfTasksCommand(AbstractBuildCommand):
44 | def __init__(self, builder):
45 | AbstractBuildCommand.__init__(self, builder, command_name='find_dependencies_of_tasks')
46 |
47 | def execute(self):
48 | self._builder.find_dependencies()
49 |
50 |
51 | class GenerateSortedBuildTasksCommand(AbstractBuildCommand):
52 | def __init__(self, builder):
53 | AbstractBuildCommand.__init__(self, builder, command_name='generate_build_tasks')
54 |
55 | def execute(self):
56 | self._builder.generate_sorted_build_tasks()
57 |
58 |
59 | class UpdateApkCreatedTimeCommand(AbstractBuildCommand):
60 | def __init__(self, builder):
61 | AbstractBuildCommand.__init__(self, builder, command_name='update_apk_created_time')
62 |
63 | def execute(self):
64 | self._builder.update_apk_created_time()
65 |
66 |
67 | class ExecuteCleanBuildCommand(AbstractBuildCommand):
68 | def __init__(self, builder):
69 | AbstractBuildCommand.__init__(self, builder, command_name='execute_clean_build')
70 |
71 | def execute(self):
72 | self._builder.clean_build()
73 |
74 |
75 | class ExecuteIncrementalBuildCommand(AbstractBuildCommand):
76 | def __init__(self, builder):
77 | AbstractBuildCommand.__init__(self, builder, command_name='execute_incremental_build')
78 |
79 | def execute(self):
80 | self._builder.incremental_build()
81 |
82 |
83 | class CompileCommand(MacroCommand):
84 | def __init__(self, name, invoker):
85 | MacroCommand.__init__(self, name)
86 | self._invoker = invoker
87 | self._setup()
88 |
89 | def _setup(self):
90 | self.add_command(IncAaptCommand(self.command_name, self._invoker))
91 | self.add_command(IncJavacCommand(self.command_name, self._invoker))
92 | self.add_command(IncDexCommand(self.command_name, self._invoker))
93 |
94 |
95 | class IncAaptCommand(MacroCommand):
96 | def __init__(self, pro, invoker):
97 | MacroCommand.__init__(self, '{}_inc_res_compile'.format(pro))
98 | self._invoker = invoker
99 |
100 | def execute(self):
101 | self._invoker.run_aapt_task()
102 |
103 |
104 | class IncJavacCommand(MacroCommand):
105 | def __init__(self, pro, invoker):
106 | MacroCommand.__init__(self, '{}_inc_javac_compile'.format(pro))
107 | self._invoker = invoker
108 |
109 | def execute(self):
110 | self._invoker.run_javac_task()
111 |
112 |
113 | class IncDexCommand(MacroCommand):
114 | def __init__(self, pro, invoker):
115 | MacroCommand.__init__(self, '{}_inc_dex_compile'.format(pro))
116 | self._invoker = invoker
117 |
118 | def execute(self):
119 | self._invoker.run_dex_task()
120 |
121 |
122 | class SyncCommand(MacroCommand):
123 | def __init__(self, sync_client, command_name):
124 | MacroCommand.__init__(self, command_name=command_name)
125 | self._sync_client = sync_client
126 |
--------------------------------------------------------------------------------
/freeline/freeline_core/command.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 | from utils import generate_random_string
4 | from logger import Logger
5 |
6 |
7 | class AbstractCommand(object):
8 | TPL_COMMAND_DEBUG_MSG = '[{}] {}'
9 |
10 | def __init__(self, command_name=None):
11 | self.command_name = generate_random_string() if not command_name else command_name
12 |
13 | def execute(self):
14 | raise NotImplementedError
15 |
16 | def debug(self, message):
17 | Logger.debug(AbstractBuildCommand.TPL_COMMAND_DEBUG_MSG.format(self.command_name, message))
18 |
19 | def __repr__(self):
20 | return self.command_name
21 |
22 | __str__ = __repr__
23 |
24 |
25 | class MacroCommand(AbstractCommand):
26 | def __init__(self, command_name=None):
27 | AbstractCommand.__init__(self, command_name=command_name)
28 | self.command_list = []
29 |
30 | def add_command(self, command):
31 | if isinstance(command, AbstractCommand):
32 | self.command_list.append(command)
33 |
34 | def remove_command(self, command):
35 | self.command_list.remove(command)
36 |
37 | def execute(self):
38 | map(lambda command: command.execute(), self.command_list)
39 |
40 |
41 | class AbstractBuildCommand(MacroCommand):
42 | def __init__(self, builder, command_name=None):
43 | MacroCommand.__init__(self, command_name=command_name)
44 | self._builder = builder
45 |
46 |
47 | class AbstractCleanBuildCommand(AbstractBuildCommand):
48 | def __init__(self, builder, command_name=None):
49 | AbstractBuildCommand.__init__(self, builder, command_name=command_name)
50 |
51 | def execute(self):
52 | raise NotImplementedError
53 |
54 |
55 | class AbstractIncrementalBuildCommand(AbstractBuildCommand):
56 | def __init__(self, builder, command_name=None):
57 | AbstractBuildCommand.__init__(self, builder, command_name=command_name)
58 |
59 | def execute(self):
60 | raise NotImplementedError
61 |
--------------------------------------------------------------------------------
/freeline/freeline_core/cursor.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 |
3 | from terminal import Terminal
4 |
5 |
6 | class Cursor(object):
7 | def __init__(self, term=None):
8 | self.term = Terminal() if term is None else term
9 | self._stream = self.term.stream
10 | self._saved = False
11 |
12 | def write(self, s):
13 | self._stream.write(s)
14 |
15 | def save(self):
16 | self.write(self.term.save)
17 | self._saved = True
18 |
19 | def restore(self):
20 | if self._saved:
21 | self.write(self.term.restore)
22 |
23 | def flush(self):
24 | self._stream.flush()
25 |
26 | def newline(self):
27 | self.write(self.term.move_down)
28 | self.write(self.term.clear_bol)
29 |
30 | def clear_lines(self, num_lines=0):
31 | for i in range(num_lines):
32 | self.write(self.term.clear_eol)
33 | self.write(self.term.move_down)
34 | for i in range(num_lines):
35 | self.write(self.term.move_up)
36 |
--------------------------------------------------------------------------------
/freeline/freeline_core/exceptions.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 |
3 |
4 | class NoConfigFoundException(Exception):
5 | def __init__(self, path):
6 | Exception.__init__(self, '{} not found, please execute gradlew checkBeforeCleanBuild first.'.format(path))
7 |
8 |
9 | class EnvironmentException(Exception):
10 | def __init__(self, message):
11 | Exception.__init__(self, message)
12 |
13 |
14 | class FreelineException(Exception):
15 | def __init__(self, message, cause):
16 | Exception.__init__(self, message)
17 | self.cause = cause
18 |
19 |
20 | class NoDeviceFoundException(FreelineException):
21 | def __init__(self, message, cause):
22 | FreelineException.__init__(self, message, cause)
23 |
24 |
25 | class CheckSyncStateException(FreelineException):
26 | def __init__(self, message, cause):
27 | FreelineException.__init__(self, message, cause)
28 |
29 |
30 | class NoInstallationException(FreelineException):
31 | def __init__(self, message, cause):
32 | FreelineException.__init__(self, message, cause)
33 |
34 |
35 | class FileMissedException(FreelineException):
36 | def __init__(self, message, cause):
37 | FreelineException.__init__(self, message, cause)
38 |
39 |
40 | class UsbConnectionException(FreelineException):
41 | def __init__(self, message, cause):
42 | FreelineException.__init__(self, message, cause)
43 |
--------------------------------------------------------------------------------
/freeline/freeline_core/freeline_build.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 | from command import AbstractCommand
4 | from exceptions import NoConfigFoundException
5 | from logger import Logger
6 |
7 |
8 | class FreelineBuildCommand(AbstractCommand):
9 | def __init__(self, config, task_engine=None):
10 | AbstractCommand.__init__(self, command_name='freeline_build_command')
11 | self._config = config
12 | self._task_engine = task_engine
13 | self._project_type = None
14 | self._dispatch_policy = None
15 | self._builder = None
16 | self._scan_command = None
17 | self._build_command = None
18 | self._setup()
19 |
20 | def execute(self):
21 | file_changed_dict = self._scan_command.execute()
22 |
23 | if self._dispatch_policy.is_need_clean_build(self._config, file_changed_dict):
24 | self._setup_clean_builder(file_changed_dict)
25 | from build_commands import CleanBuildCommand
26 | self._build_command = CleanBuildCommand(self._builder)
27 | else:
28 | # only flush changed list when your project need a incremental build.
29 | Logger.debug('file changed list:')
30 | Logger.debug(file_changed_dict)
31 | self._setup_inc_builder(file_changed_dict)
32 | from build_commands import IncrementalBuildCommand
33 | self._build_command = IncrementalBuildCommand(self._builder)
34 |
35 | self._build_command.execute()
36 |
37 | def _setup(self):
38 | if not self._config:
39 | raise NoConfigFoundException
40 |
41 | if 'project_type' in self._config:
42 | self._project_type = self._config['project_type']
43 | if self._project_type == 'gradle':
44 | from gradle_tools import GradleScanChangedFilesCommand, GradleDispatchPolicy
45 | self._scan_command = GradleScanChangedFilesCommand(self._config)
46 | self._dispatch_policy = GradleDispatchPolicy()
47 |
48 | def _setup_clean_builder(self, file_changed_dict):
49 | if self._project_type == 'gradle':
50 | from gradle_clean_build import GradleCleanBuilder
51 | project_info = self._scan_command.project_info
52 | self._builder = GradleCleanBuilder(self._config, self._task_engine, project_info=project_info)
53 |
54 | def _setup_inc_builder(self, file_changed_dict):
55 | if self._project_type == 'gradle':
56 | project_info = self._scan_command.project_info
57 | from gradle_inc_build import GradleIncBuilder
58 | self._builder = GradleIncBuilder(file_changed_dict, self._config, self._task_engine,
59 | project_info=project_info)
60 |
61 |
62 | class DispatchPolicy(object):
63 | """
64 | file_changed_dict:
65 |
66 | 'projects': {
67 | bundle1: {
68 | 'js': [],
69 | 'assets': [],
70 | 'res': [],
71 | 'src': [],
72 | 'manifest': [],
73 | 'pom': []
74 | },
75 | bundle2: {
76 | 'js': [],
77 | 'assets': [],
78 | 'res': [],
79 | 'src': [],
80 | 'manifest': [],
81 | 'pom': []
82 | },
83 | ...
84 | },
85 |
86 | 'build_info': {
87 | 'last_clean_build_time': int,
88 | 'root_pom_changed': bool
89 | }
90 | """
91 |
92 | def is_need_clean_build(self, config, file_changed_dict):
93 | raise NotImplementedError
94 |
95 |
96 | class ScanChangedFilesCommand(AbstractCommand):
97 | def __init__(self):
98 | AbstractCommand.__init__(self, command_name='scan_changed_files_command')
99 |
100 | def execute(self):
101 | raise NotImplementedError
102 |
--------------------------------------------------------------------------------
/freeline/freeline_core/gradle_clean_build.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 |
4 | import os
5 |
6 | from android_tools import InstallApkTask, CleanAllCacheTask
7 | from builder import CleanBuilder
8 | from gradle_tools import GenerateFileStatTask, BuildBaseResourceTask, get_project_info, GenerateAptFilesStatTask, \
9 | get_gradle_executable
10 | from task import CleanBuildTask, Task
11 | from utils import cexec, load_json_cache, write_json_cache
12 | from logger import Logger
13 |
14 |
15 | class GradleCleanBuilder(CleanBuilder):
16 | def __init__(self, config, task_engine, project_info=None, wait_for_debugger=False):
17 | CleanBuilder.__init__(self, config, task_engine, builder_name='gradle_clean_builder')
18 | self._root_task = None
19 | self._project_info = project_info
20 | self._wait_for_debugger = wait_for_debugger
21 |
22 | def check_build_environment(self):
23 | CleanBuilder.check_build_environment(self)
24 | if self._project_info is None:
25 | project_info_cache_path = os.path.join(self._config['build_cache_dir'], 'project_info_cache.json')
26 | if os.path.exists(project_info_cache_path):
27 | self._project_info = load_json_cache(project_info_cache_path)
28 | else:
29 | self._project_info = get_project_info(self._config)
30 |
31 | def find_dependencies(self):
32 | pass
33 |
34 | def generate_sorted_build_tasks(self):
35 | # tasks' order:
36 | # 1. generate file stat / check before clean build
37 | # 2. clean build
38 | # 3. install / clean cache
39 | # 4. build base res / generate project info cache
40 | build_task = GradleCleanBuildTask(self._config)
41 | install_task = InstallApkTask(self._adb, self._config, wait_for_debugger=self._wait_for_debugger)
42 | clean_all_cache_task = CleanAllCacheTask(self._config['build_cache_dir'], ignore=[
43 | 'stat_cache.json', 'stat_cache_md5.json', 'apktime', 'jar_dependencies.json', 'resources_dependencies.json',
44 | 'public_keeper.xml', 'assets_dependencies.json', 'freeline_annotation_info.json'])
45 | build_base_resource_task = BuildBaseResourceTask(self._config, self._project_info)
46 | generate_stat_task = GenerateFileStatTask(self._config)
47 | append_stat_task = GenerateFileStatTask(self._config, is_append=True)
48 | read_project_info_task = GradleReadProjectInfoTask(self._config)
49 | generate_project_info_task = GradleGenerateProjectInfoTask(self._config)
50 | generate_apt_file_stat_task = GenerateAptFilesStatTask()
51 |
52 | # generate_stat_task.add_child_task(read_project_info_task)
53 | build_task.add_child_task(clean_all_cache_task)
54 | build_task.add_child_task(install_task)
55 | clean_all_cache_task.add_child_task(build_base_resource_task)
56 | clean_all_cache_task.add_child_task(generate_project_info_task)
57 | clean_all_cache_task.add_child_task(append_stat_task)
58 | clean_all_cache_task.add_child_task(generate_apt_file_stat_task)
59 | read_project_info_task.add_child_task(build_task)
60 | self._root_task = [generate_stat_task, read_project_info_task]
61 |
62 | def clean_build(self):
63 | self._task_engine.add_root_task(self._root_task)
64 | self._task_engine.start()
65 |
66 |
67 | class GradleReadProjectInfoTask(Task):
68 | def __init__(self, config):
69 | Task.__init__(self, 'read_project_info_task')
70 | self._config = config
71 |
72 | def execute(self):
73 | command = '{} -q checkBeforeCleanBuild'.format(get_gradle_executable(self._config))
74 | output, err, code = cexec(command.split(' '), callback=None)
75 | if code != 0:
76 | from exceptions import FreelineException
77 | raise FreelineException('freeline failed when read project info with script: {}'.format(command),
78 | '{}\n{}'.format(output, err))
79 |
80 |
81 | class GradleGenerateProjectInfoTask(Task):
82 | def __init__(self, config):
83 | Task.__init__(self, 'generate_project_info_task')
84 |
85 | def execute(self):
86 | # reload project info
87 | from dispatcher import read_freeline_config
88 | config = read_freeline_config()
89 |
90 | write_json_cache(os.path.join(config['build_cache_dir'], 'project_info_cache.json'),
91 | get_project_info(config))
92 |
93 |
94 | class GradleCleanBuildTask(CleanBuildTask):
95 | def __init__(self, config):
96 | CleanBuildTask.__init__(self, 'gradle_clean_build_task', config)
97 |
98 | def execute(self):
99 | # reload config
100 | from dispatcher import read_freeline_config
101 | self._config = read_freeline_config()
102 |
103 | cwd = self._config['build_script_work_directory'].strip()
104 | if not cwd or not os.path.isdir(cwd):
105 | cwd = None
106 |
107 | command = self._config['build_script']
108 | command += ' -P freelineBuild=true'
109 | if 'auto_dependency' in self._config and not self._config['auto_dependency']:
110 | command += ' -PdisableAutoDependency=true'
111 | if Logger.debuggable:
112 | command += ' --stacktrace'
113 | self.debug(command)
114 | self.debug("Gradle build task is running, please wait a minute...")
115 | output, err, code = cexec(command.split(' '), callback=None, cwd=cwd)
116 | if code != 0:
117 | from exceptions import FreelineException
118 | raise FreelineException('build failed with script: {}'.format(command), '{}\n{}'.format(output, err))
119 |
--------------------------------------------------------------------------------
/freeline/freeline_core/hackwindows.py:
--------------------------------------------------------------------------------
1 | TIOCGWINSZ = 1074295912
2 |
3 |
4 | def fcntl(fd, op, arg=0):
5 | return 0
6 |
7 |
8 | def ioctl(fd, op, arg=0, mutable_flag=True):
9 | if mutable_flag:
10 | return 0
11 | else:
12 | return ""
13 |
14 |
15 | def flock(fd, op):
16 | return
17 |
18 |
19 | def lockf(fd, operation, length=0, start=0, whence=0):
20 | return
21 |
--------------------------------------------------------------------------------
/freeline/freeline_core/init.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 | import os
4 |
5 | from exceptions import FreelineException
6 | from utils import is_windows_system, cexec, copy, get_file_content
7 |
8 | is_windows = is_windows_system()
9 |
10 |
11 | def init():
12 | project_dir = os.getcwd()
13 | symlink('freeline', project_dir, 'freeline.py')
14 |
15 | if is_windows:
16 | symlink('freeline', project_dir, 'freeline_core')
17 |
18 | from gradle_tools import get_all_modules
19 | modules = get_all_modules(project_dir)
20 | for m in modules:
21 | if is_main_project(m['path']):
22 | main_module = m
23 | break
24 |
25 | if not main_module:
26 | raise FreelineException('main module not found', 'set main module first')
27 |
28 | print('find main module: ' + main_module['name'])
29 | args = []
30 | if is_windows:
31 | args.append('gradlew.bat')
32 | else:
33 | args.append('./gradlew')
34 | args.append(':{}:checkBeforeCleanBuild'.format(main_module['name']))
35 | print('freeline is reading project info, please wait a moment...')
36 | output, err, code = cexec(args, cwd=project_dir)
37 | if code != 0:
38 | raise FreelineException('freeline failed when read project info with script: {}'.format(args),
39 | '{}\n{}'.format(output, err))
40 | print('freeline init success')
41 |
42 |
43 | def is_main_project(module):
44 | config_path = os.path.join(module, 'build.gradle')
45 | if os.path.exists(config_path):
46 | content = get_file_content(config_path)
47 | if "apply plugin: 'com.antfortune.freeline'" in content:
48 | return True
49 | return False
50 |
51 |
52 | def symlink(base_dir, target_dir, fn):
53 | base_path = os.path.join(base_dir, fn)
54 | target_path = os.path.join(target_dir, fn)
55 |
56 | if not os.path.exists(base_path):
57 | raise FreelineException('file missing: {}'.format(base_path), ' Maybe you should sync freeline repo')
58 |
59 | if os.path.exists(target_path):
60 | os.remove(target_path)
61 |
62 | if is_windows_system():
63 | copy(base_path, target_path)
64 | else:
65 | os.symlink(base_path, target_path)
66 |
--------------------------------------------------------------------------------
/freeline/freeline_core/logger.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 |
4 | import Queue
5 | import logging
6 | import os
7 | import threading
8 | import time
9 | import traceback
10 |
11 | from utils import print_json, is_windows_system
12 |
13 | FAILURE = -1
14 | READY = 0
15 | WAITING = 1
16 | WORKING = 2
17 | SUCCESS = 3
18 |
19 |
20 | class LoggerWorker(threading.Thread):
21 | def __init__(self, logger, stop_event):
22 | threading.Thread.__init__(self)
23 | self.setDaemon(True)
24 |
25 | if not isinstance(logger, Logger):
26 | raise Exception('LoggerWorker should be set up with freeline.logger.Logger')
27 |
28 | self._logger = logger
29 | self._stop_event = stop_event
30 |
31 | def run(self):
32 | while not self._stop_event.isSet():
33 | if self._logger.debuggable:
34 | message = Logger.debug_messages_queue.get()
35 | Logger.print_debug_message(message)
36 | else:
37 | self._logger.update()
38 | time.sleep(self._logger.interval)
39 |
40 | # if in debug mode, clean the debug messages queue
41 | if self._logger.debuggable:
42 | Logger.flush_debug_messages()
43 | else:
44 | self._logger.update()
45 |
46 |
47 | class Logger(object):
48 | # TODO: check screen height before log messages
49 | debuggable = False
50 | debug_messages_queue = Queue.Queue()
51 | temp_backup_queue = Queue.Queue()
52 | info_message_array = []
53 | TPL_DEBUG_MESSAGE = '[DEBUG] {}'
54 |
55 | def __init__(self, debuggable=False, interval=0.1, unit="s"):
56 | self.debuggable = debuggable
57 | self.interval = interval
58 | self.unit = unit
59 |
60 | if not is_windows_system():
61 | from cursor import Cursor
62 | from terminal import Terminal
63 | self.cursor = Cursor(Terminal())
64 |
65 | self.sorted_tasks = []
66 |
67 | self.tpl_running_task = '[+][{}] {} in {}{}\n'
68 | self.tpl_waiting_task = '[+][{}] {}\n'
69 | self.tpl_finished_task = '[-][{}] {} in {}{}\n'
70 | # self.tpl_faied_task = '[-]{}:{} in {}{}\n'
71 | logging.basicConfig(level=logging.DEBUG)
72 |
73 | def set_sorted_tasks(self, sorted_tasks):
74 | self.sorted_tasks = sorted_tasks
75 |
76 | def draw(self):
77 | # if len(self.sorted_tasks) > 0:
78 | self.cursor.restore()
79 | self._draw()
80 | self.cursor.flush()
81 |
82 | def clear_space(self):
83 | self.cursor.restore()
84 | self.cursor.clear_lines(self._calculate_lines_num())
85 | self.cursor.save()
86 |
87 | def update(self):
88 | self.clear_space()
89 | self.draw()
90 |
91 | def reset(self):
92 | if not self.debuggable:
93 | self.clear_space()
94 | self.sorted_tasks = []
95 | Logger.info_message_array = []
96 |
97 | @staticmethod
98 | def info(message):
99 | Logger.info_message_array.append(message)
100 |
101 | @staticmethod
102 | def debug(message):
103 | Logger.debug_messages_queue.put(message)
104 | Logger.temp_backup_queue.put(message)
105 |
106 | @staticmethod
107 | def warn(message):
108 | pass
109 |
110 | @staticmethod
111 | def error(message):
112 | pass
113 |
114 | @staticmethod
115 | def print_debug_message(message):
116 | if isinstance(message, dict) or isinstance(message, list):
117 | print_json(message)
118 | else:
119 | print(Logger.TPL_DEBUG_MESSAGE.format(message))
120 |
121 | @staticmethod
122 | def flush_debug_messages():
123 | while not Logger.debug_messages_queue.empty():
124 | message = Logger.debug_messages_queue.get()
125 | Logger.print_debug_message(message)
126 |
127 | @staticmethod
128 | def write_error_log(exception=None, extra=None):
129 | import json
130 | try:
131 | log_path = get_error_log_path()
132 | with open(log_path, 'w') as fp:
133 | while not Logger.temp_backup_queue.empty():
134 | message = Logger.temp_backup_queue.get(timeout=0.5)
135 | if isinstance(message, dict) or isinstance(message, list):
136 | fp.write(json.dumps(message, indent=4, separators=(',', ': ')))
137 | else:
138 | fp.write(message)
139 | fp.write('\n')
140 |
141 | # write extra info
142 | if exception:
143 | fp.write(exception)
144 | return log_path
145 | except Exception as e:
146 | print(traceback.format_exc())
147 | print(e.message)
148 | return None
149 |
150 | def _calculate_lines_num(self):
151 | lines_count = 0
152 | for task in self.sorted_tasks:
153 | if task.can_show_log:
154 | lines_count += 1
155 | return lines_count + len(Logger.info_message_array) + 1
156 |
157 | def _draw(self):
158 | # map(lambda task: self.cursor.write(self._get_formatted_message(task)), self.sorted_tasks)
159 | map(lambda message: self.cursor.write(message + '\n'), Logger.info_message_array)
160 | map(lambda task: self.cursor.write(self._get_formatted_message(task)),
161 | filter(lambda task: task.can_show_log(), self.sorted_tasks))
162 |
163 | def _get_formatted_message(self, task):
164 | return {
165 | FAILURE: self.tpl_finished_task.format(task.name, 'failed.', task.cost_time, self.unit),
166 | READY: self.tpl_running_task.format(task.name, 'not start.', 'N/A', self.unit),
167 | WAITING: self.tpl_waiting_task.format(task.name, 'waiting...'),
168 | WORKING: self.tpl_running_task.format(task.name, task.running_message,
169 | round(time.time() - task.run_start_time, 1), self.unit),
170 | SUCCESS: self.tpl_finished_task.format(task.name, task.finished_message, task.cost_time, self.unit)
171 | }.get(task.status, 'NULL')
172 |
173 |
174 | def get_error_log_path():
175 | return os.path.join(get_error_log_dir(), time.strftime('%y-%m-%d %H-%M-%S') + '.log')
176 |
177 |
178 | def get_error_log_dir():
179 | dir_path = os.path.join(os.path.expanduser('~'), '.freeline', 'logs')
180 | if not os.path.exists(dir_path):
181 | os.makedirs(dir_path)
182 | return dir_path
183 |
--------------------------------------------------------------------------------
/freeline/freeline_core/task.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 | import threading
4 | import time
5 | import traceback
6 |
7 | from exceptions import FreelineException
8 |
9 | from logger import Logger, FAILURE, READY, WAITING, WORKING, SUCCESS
10 |
11 |
12 | class Task(object):
13 | def __init__(self, name):
14 | self.name = name
15 | self.parent_tasks = []
16 | self.child_tasks = []
17 |
18 | self.status = READY # -1: failed; 0: not start; 1: waiting; 2: working; 3: success;
19 | self.start_time = 0
20 | self.run_start_time = 0
21 | self.cost_time = 0
22 | self.running_message = 'running...'
23 | self.finished_message = 'finished.'
24 | self.condition = threading.Condition()
25 | self.interrupted_exception = None
26 |
27 | def __repr__(self):
28 | return "[{}]".format(self.name)
29 |
30 | def add_parent_task(self, task):
31 | if task not in self.parent_tasks:
32 | self.parent_tasks.append(task)
33 | task.add_child_task(self)
34 |
35 | def add_child_task(self, task):
36 | if task not in self.child_tasks:
37 | self.child_tasks.append(task)
38 | task.add_parent_task(self)
39 |
40 | def is_all_parent_finished(self):
41 | for task in self.parent_tasks:
42 | if task.status != SUCCESS and task.status != FAILURE:
43 | return False
44 | return True
45 |
46 | def wait(self):
47 | self.condition.acquire()
48 | self.condition.wait()
49 | self.condition.release()
50 |
51 | def notify(self):
52 | self.condition.acquire()
53 | self.condition.notify()
54 | self.condition.release()
55 |
56 | def execute(self):
57 | raise NotImplementedError
58 |
59 | def can_show_log(self):
60 | return self.status == SUCCESS or self.status == WORKING or self.status == FAILURE
61 |
62 | def debug(self, message):
63 | Logger.debug('[{}] {}'.format(self.name, message))
64 |
65 |
66 | class CleanBuildTask(Task):
67 | def __init__(self, name, config):
68 | Task.__init__(self, name)
69 | self._config = config
70 |
71 | def execute(self):
72 | raise NotImplementedError
73 |
74 |
75 | class IncrementalBuildTask(Task):
76 | def __init__(self, name):
77 | Task.__init__(self, name)
78 |
79 | def execute(self):
80 | raise NotImplementedError
81 |
82 |
83 | class SyncTask(Task):
84 | def __init__(self, client, name):
85 | Task.__init__(self, name)
86 | self._client = client
87 |
88 | def execute(self):
89 | raise NotImplementedError
90 |
91 |
92 | class ExecutableTask(object):
93 | def __init__(self, task, engine):
94 | self.task = task
95 | self.engine = engine
96 | self._tpl_debug_message = '[{}] {}'
97 |
98 | def __repr__(self):
99 | return "".format(self.task.name)
100 |
101 | def debug(self, message):
102 | Logger.debug(self._tpl_debug_message.format(self.task.name, message))
103 |
104 | def execute(self):
105 | # self.debug('{} start to execute...'.format(self.task.name))
106 | self.task.start_time = time.time()
107 | self.task.status = WAITING
108 | while not self.task.is_all_parent_finished():
109 | # self.debug('{} waiting...'.format(self.task.name))
110 | self.task.wait()
111 | self.task.run_start_time = time.time()
112 | self.task.status = WORKING
113 | self.debug('{} start to run after waiting {}s'.format(self.task.name,
114 | round(self.task.run_start_time - self.task.start_time,
115 | 1)))
116 | # check if task need to interrupt before being executing
117 | if self.task.interrupted_exception is not None:
118 | self.task.status = FAILURE
119 | self._pass_interrupted_exception()
120 | return
121 |
122 | try:
123 | self.task.execute()
124 | self.task.status = SUCCESS
125 | except FreelineException as e:
126 | self.task.interrupted_exception = e
127 | self.task.status = FAILURE
128 | except:
129 | self.task.interrupted_exception = FreelineException('unexpected exception within task',
130 | traceback.format_exc())
131 | self.task.status = FAILURE
132 |
133 | self.task.cost_time = round(time.time() - self.task.run_start_time, 1)
134 | self.debug('{} finish in {}s'.format(self.task.name, round(self.task.cost_time, 1)))
135 |
136 | # check if task need to interrupt after being executing
137 | if self.task.interrupted_exception is not None:
138 | self._pass_interrupted_exception()
139 | return
140 |
141 | for child_task in self.task.child_tasks:
142 | child_task.notify()
143 |
144 | self._check_engine_finished()
145 |
146 | def _pass_interrupted_exception(self):
147 | for child_task in self.engine.get_running_tasks():
148 | child_task.interrupted_exception = self.task.interrupted_exception
149 | child_task.notify()
150 |
151 | if self.engine.is_all_tasks_finished():
152 | self.engine.interrupt(self.task.interrupted_exception)
153 | self.engine.finish()
154 |
155 | def _check_engine_finished(self):
156 | if self.engine.is_all_tasks_finished():
157 | self.engine.finish()
158 |
159 |
160 | def find_root_tasks(task_list):
161 | return filter(lambda task: len(task.parent_tasks) == 0, task_list)
162 |
163 |
164 | def find_last_tasks(task_list):
165 | return filter(lambda task: len(task.child_tasks) == 0, task_list)
166 |
--------------------------------------------------------------------------------
/freeline/freeline_core/tracing.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | from logger import Logger
4 |
5 |
6 | class Tracing(object):
7 | def __init__(self, description):
8 | self.__name = "tracing"
9 | self.__description = description
10 | self.__start_time = 0
11 |
12 | def __enter__(self):
13 | self.__start_time = time.time()
14 |
15 | def __exit__(self, exc_type, exc_val, exc_tb):
16 | if exc_tb:
17 | return False
18 | else:
19 | self.debug(time.time() - self.__start_time)
20 | return True
21 |
22 | def debug(self, execute_time):
23 | Logger.debug('[{}] {}: {}ms'.format(self.__name, self.__description, execute_time * 1000))
24 |
--------------------------------------------------------------------------------
/freeline/freeline_core/utils.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | from __future__ import print_function
3 | import os
4 | import string
5 | import random
6 | import platform
7 | import re
8 | import hashlib
9 | import json
10 | import shutil
11 | from hashlib import md5
12 | from subprocess import Popen, PIPE
13 |
14 | import errno
15 |
16 | try:
17 | import xml.etree.cElementTree as ET
18 | except ImportError:
19 | import xml.etree.ElementTree as ET
20 |
21 |
22 | def cexec(args, callback=None, add_path=None, cwd=None):
23 | env = None
24 | if add_path:
25 | import copy
26 | env = copy.copy(os.environ)
27 | env['PATH'] = add_path + os.path.pathsep + env['PATH']
28 | p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env, cwd=cwd)
29 | output, err = p.communicate()
30 | code = p.returncode
31 |
32 | if code != 0 and callback:
33 | callback(args, code, output, err)
34 | else:
35 | return output, err, code
36 |
37 |
38 | def curl(url, body=None):
39 | code = 0
40 | err = None
41 | result = None
42 | try:
43 | import urllib2
44 | result = urllib2.urlopen(url, data=body).read().decode('utf-8').strip()
45 | except Exception as e:
46 | code = -1
47 | err = e
48 | return result, err, code
49 |
50 |
51 | def generate_random_string(length=6):
52 | return ''.join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(length))
53 |
54 |
55 | def is_windows_system():
56 | return 'Windows' in platform.system()
57 |
58 |
59 | def is_linux_system():
60 | return 'Linux' in platform.system()
61 |
62 |
63 | def copy(src, dst):
64 | try:
65 | shutil.copytree(src, dst)
66 | except OSError as e:
67 | if e.errno == errno.ENOTDIR:
68 | shutil.copy(src, dst)
69 | else:
70 | print('Directory not copied. Error: {}'.format(e.message))
71 |
72 |
73 | def get_md5(fpath):
74 | m = md5()
75 | target_file = open(fpath, 'rb')
76 | m.update(target_file.read())
77 | target_file.close()
78 | return m.hexdigest()
79 |
80 |
81 | def md5string(param):
82 | m = hashlib.md5()
83 | m.update(param.encode('utf-8'))
84 | return m.hexdigest()
85 |
86 |
87 | base = [str(x) for x in range(10)] + [chr(x) for x in range(ord('A'), ord('A') + 6)]
88 |
89 |
90 | def dec2hex(string_num):
91 | num = int(string_num)
92 | mid = []
93 | while True:
94 | if num == 0:
95 | break
96 | num, rem = divmod(num, 16)
97 | mid.append(base[rem])
98 | return ''.join([str(t) for t in mid[::-1]])
99 |
100 |
101 | def is_exe(path):
102 | return os.path.isfile(path) and os.access(path, os.X_OK)
103 |
104 |
105 | def print_json(json_obj):
106 | print(json.dumps(json_obj, indent=4, separators=(',', ': ')))
107 |
108 |
109 | def get_file_content(path):
110 | if not path or not os.path.isfile(path):
111 | return ''
112 | import codecs
113 | with codecs.open(path, encoding='utf-8') as f:
114 | return f.read()
115 |
116 |
117 | def write_file_content(target_path, content):
118 | with open(target_path, 'w') as fp:
119 | if isinstance(content, int):
120 | content = unicode(content)
121 | fp.write(content.encode('utf-8'))
122 |
123 |
124 | def load_json_cache(fpath):
125 | cache = {}
126 | if not os.path.exists(fpath):
127 | pass
128 | if os.path.isfile(fpath):
129 | try:
130 | with open(fpath, 'r') as fp:
131 | cache = json.load(fp)
132 | except Exception:
133 | pass
134 | return cache
135 |
136 |
137 | def write_json_cache(fpath, cache):
138 | try:
139 | with open(fpath, 'w') as fp:
140 | json.dump(cache, fp)
141 | except Exception:
142 | pass
143 |
144 |
145 | def calculate_typed_file_count(dir_path, ext):
146 | i = 0
147 | for dirpath, dirnames, files in os.walk(dir_path):
148 | for fn in files:
149 | if fn.endswith(ext):
150 | i += 1
151 | return i
152 |
153 |
154 | def remove_namespace(path):
155 | content = get_file_content(path)
156 | xmlstring = re.sub('xmlns="[^"]+"', '', content, count=1)
157 | return xmlstring.encode('utf-8') # to avoid UnicodeEncodeError
158 |
159 |
160 | def merge_xml(filenames):
161 | return ET.tostring(XMLCombiner(filenames).combine().getroot())
162 |
163 |
164 | def get_text_by_tag(root, tag):
165 | element = root.find(tag)
166 | return element.text if element is not None else ''
167 |
168 |
169 | class HashableDict(dict):
170 | def __hash__(self):
171 | return hash(tuple(sorted(self.items())))
172 |
173 |
174 | class XMLCombiner(object):
175 | def __init__(self, filenames):
176 | assert len(filenames) > 0, 'No filenames!'
177 | self.roots = [ET.parse(f).getroot() for f in filenames]
178 |
179 | def combine(self):
180 | for r in self.roots[1:]:
181 | # combine each element with the first one, and update that
182 | self.combine_element(self.roots[0], r)
183 | # return the string representation
184 | return ET.ElementTree(self.roots[0])
185 |
186 | def combine_element(self, one, other):
187 | mapping = {(el.tag, HashableDict(el.attrib)): el for el in one}
188 | for el in other:
189 | if len(el) == 0:
190 | try:
191 | # Update the text
192 | mapping[(el.tag, HashableDict(el.attrib))].text = el.text
193 | except KeyError:
194 | # An element with this name is not in the mapping
195 | mapping[(el.tag, HashableDict(el.attrib))] = el
196 | # Add it
197 | one.append(el)
198 | else:
199 | try:
200 | # Recursively process the element, and update it in the same way
201 | self.combine_element(mapping[(el.tag, HashableDict(el.attrib))], el)
202 | except KeyError:
203 | mapping[(el.tag, HashableDict(el.attrib))] = el
204 | one.append(el)
205 |
--------------------------------------------------------------------------------
/freeline/freeline_core/version.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf8 -*-
2 | import subprocess
3 | import os
4 |
5 | VERSION_FORMATTER = '{}({})'
6 | FREELINE_VERSION = 'v0.8.7'
7 |
8 |
9 | def get_freeline_version():
10 | if is_git_dir():
11 | return VERSION_FORMATTER.format(FREELINE_VERSION, get_git_short_version())
12 | else:
13 | return FREELINE_VERSION
14 |
15 |
16 | def get_git_short_version():
17 | # note: get git version
18 | # http://stackoverflow.com/questions/14989858/get-the-current-git-hash-in-a-python-script
19 | return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'])
20 |
21 |
22 | def is_git_dir():
23 | project_root_path = os.path.abspath(os.path.join(os.path.realpath(__file__), os.pardir))
24 | git_dir_path = os.path.join(project_root_path, '.git')
25 | if os.path.exists(git_dir_path) and os.path.isdir(git_dir_path):
26 | return True
27 | return False
28 |
--------------------------------------------------------------------------------
/freeline/release-tools/DexMerge.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/DexMerge.jar
--------------------------------------------------------------------------------
/freeline/release-tools/FreelineAapt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/FreelineAapt
--------------------------------------------------------------------------------
/freeline/release-tools/FreelineAapt.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/FreelineAapt.exe
--------------------------------------------------------------------------------
/freeline/release-tools/FreelineAapt_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/FreelineAapt_
--------------------------------------------------------------------------------
/freeline/release-tools/databinding-cli.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/databinding-cli.jar
--------------------------------------------------------------------------------
/freeline/release-tools/databinding-cli8.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/databinding-cli8.jar
--------------------------------------------------------------------------------
/freeline/release-tools/dexmerger:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (C) 2012 The Android Open Source Project
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Set up prog to be the path of this script, including following symlinks,
18 | # and set up progdir to be the fully-qualified pathname of its directory.
19 | prog="$0"
20 | while [ -h "${prog}" ]; do
21 | newProg=`/bin/ls -ld "${prog}"`
22 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
23 | if expr "x${newProg}" : 'x/' >/dev/null; then
24 | prog="${newProg}"
25 | else
26 | progdir=`dirname "${prog}"`
27 | prog="${progdir}/${newProg}"
28 | fi
29 | done
30 | oldwd=`pwd`
31 | progdir=`dirname "${prog}"`
32 | cd "${progdir}"
33 | progdir=`pwd`
34 | prog="${progdir}"/`basename "${prog}"`
35 | cd "${oldwd}"
36 |
37 | jarfile=dx.jar
38 | libdir="$progdir"
39 |
40 | if [ ! -r "$libdir/$jarfile" ]; then
41 | # set dx.jar location for the SDK case
42 | libdir=`dirname "$progdir"`/platform-tools/lib
43 | fi
44 |
45 |
46 | if [ ! -r "$libdir/$jarfile" ]; then
47 | # set dx.jar location for the Android tree case
48 | libdir=`dirname "$progdir"`/framework
49 | fi
50 |
51 | if [ ! -r "$libdir/$jarfile" ]; then
52 | echo `basename "$prog"`": can't find $jarfile"
53 | exit 1
54 | fi
55 |
56 | # By default, give dexmerger a max heap size of 1 gig. This can be overridden
57 | # by using a "-J" option (see below).
58 | defaultMx="-Xmx1024M"
59 |
60 | # The following will extract any initial parameters of the form
61 | # "-J" from the command line and pass them to the Java
62 | # invocation (instead of to dexmerger). This makes it possible for you to add
63 | # a command-line parameter such as "-JXmx256M" in your scripts, for
64 | # example. "java" (with no args) and "java -X" give a summary of
65 | # available options.
66 |
67 | javaOpts=""
68 |
69 | while expr "x$1" : 'x-J' >/dev/null; do
70 | opt=`expr "x$1" : 'x-J\(.*\)'`
71 | javaOpts="${javaOpts} -${opt}"
72 | if expr "x${opt}" : "xXmx[0-9]" >/dev/null; then
73 | defaultMx="no"
74 | fi
75 | shift
76 | done
77 |
78 | if [ "${defaultMx}" != "no" ]; then
79 | javaOpts="${javaOpts} ${defaultMx}"
80 | fi
81 |
82 | if [ "$OSTYPE" = "cygwin" ]; then
83 | # For Cygwin, convert the jarfile path into native Windows style.
84 | jarpath=`cygpath -w "$libdir/$jarfile"`
85 | else
86 | jarpath="$libdir/$jarfile"
87 | fi
88 |
89 | exec java $javaOpts -cp "$jarpath" com.android.dx.merge.DexMerger "$@"
90 |
--------------------------------------------------------------------------------
/freeline/release-tools/dx:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (C) 2007 The Android Open Source Project
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Set up prog to be the path of this script, including following symlinks,
18 | # and set up progdir to be the fully-qualified pathname of its directory.
19 | prog="$0"
20 | while [ -h "${prog}" ]; do
21 | newProg=`/bin/ls -ld "${prog}"`
22 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
23 | if expr "x${newProg}" : 'x/' >/dev/null; then
24 | prog="${newProg}"
25 | else
26 | progdir=`dirname "${prog}"`
27 | prog="${progdir}/${newProg}"
28 | fi
29 | done
30 | oldwd=`pwd`
31 | progdir=`dirname "${prog}"`
32 | cd "${progdir}"
33 | progdir=`pwd`
34 | prog="${progdir}"/`basename "${prog}"`
35 | cd "${oldwd}"
36 |
37 | jarfile=dx.jar
38 | libdir="freeline/release-tools"
39 |
40 | if [ ! -r "$libdir/$jarfile" ]; then
41 | # set dx.jar location for the SDK case
42 | libdir="$libdir/lib"
43 | fi
44 |
45 |
46 | if [ ! -r "$libdir/$jarfile" ]; then
47 | # set dx.jar location for the Android tree case
48 | libdir=`dirname "$progdir"`/framework
49 | fi
50 |
51 | if [ ! -r "$libdir/$jarfile" ]; then
52 | echo `basename "$prog"`": can't find $jarfile"
53 | exit 1
54 | fi
55 |
56 | # By default, give dx a max heap size of 1 gig. This can be overridden
57 | # by using a "-J" option (see below).
58 | defaultMx="-Xmx1024M"
59 |
60 | # The following will extract any initial parameters of the form
61 | # "-J" from the command line and pass them to the Java
62 | # invocation (instead of to dx). This makes it possible for you to add
63 | # a command-line parameter such as "-JXmx256M" in your scripts, for
64 | # example. "java" (with no args) and "java -X" give a summary of
65 | # available options.
66 |
67 | javaOpts=""
68 |
69 | while expr "x$1" : 'x-J' >/dev/null; do
70 | opt=`expr "x$1" : 'x-J\(.*\)'`
71 | javaOpts="${javaOpts} -${opt}"
72 | if expr "x${opt}" : "xXmx[0-9]" >/dev/null; then
73 | defaultMx="no"
74 | fi
75 | shift
76 | done
77 |
78 | if [ "${defaultMx}" != "no" ]; then
79 | javaOpts="${javaOpts} ${defaultMx}"
80 | fi
81 |
82 | if [ "$OSTYPE" = "cygwin" ]; then
83 | # For Cygwin, convert the jarfile path into native Windows style.
84 | jarpath=`cygpath -w "$libdir/$jarfile"`
85 | else
86 | jarpath="$libdir/$jarfile"
87 | fi
88 |
89 | exec java $javaOpts -jar "$jarpath" "$@"
90 |
--------------------------------------------------------------------------------
/freeline/release-tools/dx.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | REM Copyright (C) 2007 The Android Open Source Project
3 | REM
4 | REM Licensed under the Apache License, Version 2.0 (the "License");
5 | REM you may not use this file except in compliance with the License.
6 | REM You may obtain a copy of the License at
7 | REM
8 | REM http://www.apache.org/licenses/LICENSE-2.0
9 | REM
10 | REM Unless required by applicable law or agreed to in writing, software
11 | REM distributed under the License is distributed on an "AS IS" BASIS,
12 | REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | REM See the License for the specific language governing permissions and
14 | REM limitations under the License.
15 |
16 | REM don't modify the caller's environment
17 | setlocal
18 |
19 | REM Locate dx.jar in the directory where dx.bat was found and start it.
20 |
21 | REM Set up prog to be the path of this script, including following symlinks,
22 | REM and set up progdir to be the fully-qualified pathname of its directory.
23 | set prog=%~f0
24 |
25 | rem Check we have a valid Java.exe in the path.
26 | set java_exe=
27 | if exist "%~dp0..\tools\lib\find_java.bat" call "%~dp0..\tools\lib\find_java.bat"
28 | if exist "%~dp0..\..\tools\lib\find_java.bat" call "%~dp0..\..\tools\lib\find_java.bat"
29 | if not defined java_exe goto :EOF
30 |
31 | set jarfile=dx.jar
32 | set "frameworkdir=%~dp0"
33 | rem frameworkdir must not end with a dir sep.
34 | set "frameworkdir=%frameworkdir:~0,-1%"
35 |
36 | if exist "%frameworkdir%\%jarfile%" goto JarFileOk
37 | set "frameworkdir=%~dp0lib"
38 |
39 | if exist "%frameworkdir%\%jarfile%" goto JarFileOk
40 | set "frameworkdir=%~dp0..\framework"
41 |
42 | :JarFileOk
43 |
44 | set "jarpath=%frameworkdir%\%jarfile%"
45 |
46 | set javaOpts=
47 | set args=
48 |
49 | REM By default, give dx a max heap size of 1 gig and a stack size of 1meg.
50 | rem This can be overridden by using "-JXmx..." and "-JXss..." options below.
51 | set defaultXmx=-Xmx1024M
52 | set defaultXss=-Xss1m
53 |
54 | REM Capture all arguments that are not -J options.
55 | REM Note that when reading the input arguments with %1, the cmd.exe
56 | REM automagically converts --name=value arguments into 2 arguments "--name"
57 | REM followed by "value". Dx has been changed to know how to deal with that.
58 | set params=
59 |
60 | :firstArg
61 | if [%1]==[] goto endArgs
62 | set a=%~1
63 |
64 | if [%defaultXmx%]==[] goto notXmx
65 | if %a:~0,5% NEQ -JXmx goto notXmx
66 | set defaultXmx=
67 | :notXmx
68 |
69 | if [%defaultXss%]==[] goto notXss
70 | if %a:~0,5% NEQ -JXss goto notXss
71 | set defaultXss=
72 | :notXss
73 |
74 | if %a:~0,2% NEQ -J goto notJ
75 | set javaOpts=%javaOpts% -%a:~2%
76 | shift /1
77 | goto firstArg
78 |
79 | :notJ
80 | set params=%params% %1
81 | shift /1
82 | goto firstArg
83 |
84 | :endArgs
85 |
86 | set javaOpts=%javaOpts% %defaultXmx% %defaultXss%
87 | call "%java_exe%" %javaOpts% -Djava.ext.dirs="%frameworkdir%" -jar "%jarpath%" %params%
88 |
89 |
--------------------------------------------------------------------------------
/freeline/release-tools/dx.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/dx.jar
--------------------------------------------------------------------------------
/freeline/release-tools/jasmin:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (C) 2007 The Android Open Source Project
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Set up prog to be the path of this script, including following symlinks,
18 | # and set up progdir to be the fully-qualified pathname of its directory.
19 | prog="$0"
20 | while [ -h "${prog}" ]; do
21 | newProg=`/bin/ls -ld "${prog}"`
22 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
23 | if expr "x${newProg}" : 'x/' >/dev/null; then
24 | prog="${newProg}"
25 | else
26 | progdir=`dirname "${prog}"`
27 | prog="${progdir}/${newProg}"
28 | fi
29 | done
30 | oldwd=`pwd`
31 | progdir=`dirname "${prog}"`
32 | cd "${progdir}"
33 | progdir=`pwd`
34 | prog="${progdir}"/`basename "${prog}"`
35 | cd "${oldwd}"
36 |
37 | libdir=`dirname $progdir`/etc
38 |
39 | exec java -jar $libdir/jasmin.jar "$@"
40 |
--------------------------------------------------------------------------------
/freeline/release-tools/jasmin.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/jasmin.jar
--------------------------------------------------------------------------------
/freeline/release-tools/lib64/libc++.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zonezoen/ForGitHubProject/57fd36d6e82c2b35e3b3027749b9a09c5659d2f1/freeline/release-tools/lib64/libc++.so
--------------------------------------------------------------------------------
/freeline/release-tools/mainDexClasses:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (C) 2013 The Android Open Source Project
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | function makeTempJar ()
18 | {
19 | local tempDir=/tmp
20 | if [ ! -e "${tempDir}" ]; then
21 | tempDir=.
22 | fi
23 | local tempfile="${tempDir}/mainDexClasses-$$.tmp.jar"
24 | if [ -e "${tempfile}" ]; then
25 | echo "Failed to create temporary file" >2
26 | exit 6
27 | fi
28 | echo "${tempfile}"
29 | }
30 |
31 | function cleanTmp ()
32 | {
33 | if [ -e "${tmpOut}" ] ; then
34 | rm "${tmpOut}"
35 | fi
36 | }
37 |
38 |
39 | # Set up prog to be the path of this script, including following symlinks,
40 | # and set up progdir to be the fully-qualified pathname of its directory.
41 | prog="$0"
42 |
43 | while [ -h "${prog}" ]; do
44 | newProg=`/bin/ls -ld "${prog}"`
45 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
46 | if expr "x${newProg}" : 'x/' >/dev/null; then
47 | prog="${newProg}"
48 | else
49 | progdir=`dirname "${prog}"`
50 | prog="${progdir}/${newProg}"
51 | fi
52 | done
53 | oldwd=`pwd`
54 | progdir=`dirname "${prog}"`
55 | cd "${progdir}"
56 | progdir=`pwd`
57 | prog="${progdir}"/`basename "${prog}"`
58 | cd "${oldwd}"
59 |
60 | baserules="${progdir}"/mainDexClasses.rules
61 | if [ ! -r ${baserules} ]; then
62 | echo `basename "$prog"`": can't find mainDexClasses.rules" 1>&2
63 | exit 1
64 | fi
65 |
66 | jarfile=dx.jar
67 | libdir="$progdir"
68 |
69 | if [ ! -r "$libdir/$jarfile" ]; then
70 | # set dx.jar location for the SDK case
71 | libdir="$libdir/lib"
72 | fi
73 |
74 |
75 | if [ ! -r "$libdir/$jarfile" ]; then
76 | # set dx.jar location for the Android tree case
77 | libdir=`dirname "$progdir"`/framework
78 | fi
79 |
80 | if [ ! -r "$libdir/$jarfile" ]; then
81 | echo `basename "$prog"`": can't find $jarfile" 1>&2
82 | exit 1
83 | fi
84 |
85 | proguardExec="proguard.sh"
86 | proguard=${PROGUARD_HOME}/bin/${proguardExec}
87 |
88 | if [ ! -r "${proguard}" ]; then
89 | # set proguard location for the SDK case
90 | proguardBaseDir=`dirname "$progdir"`
91 | # "${progdir}"/../..
92 | proguardBaseDir=`dirname "$proguardBaseDir"`
93 | proguard="${proguardBaseDir}"/tools/proguard/bin/${proguardExec}
94 | fi
95 |
96 | if [ ! -r "${proguard}" ]; then
97 | # set proguard location for the Android tree case
98 | proguardBaseDir=`dirname "$proguardBaseDir"`
99 | # "${progdir}"/../../../..
100 | proguardBaseDir=`dirname "$proguardBaseDir"`
101 | proguard="${proguardBaseDir}"/external/proguard/bin/${proguardExec}
102 | fi
103 |
104 | if [ ! -r "${proguard}" ]; then
105 | proguard="`which proguard`"
106 | fi
107 |
108 | if [ -z "${proguard}" -o ! -r "${proguard}" ]; then
109 | proguard="`which ${proguardExec}`"
110 | fi
111 |
112 | if [ -z "${proguard}" -o ! -r "${proguard}" ]; then
113 | echo `basename "$prog"`": can't find ${proguardExec}" 1>&2
114 | exit 1
115 | fi
116 |
117 | shrinkedAndroidJar="${SHRINKED_ANDROID_JAR}"
118 | if [ -z "${shrinkedAndroidJar}" ]; then
119 | shrinkedAndroidJar=shrinkedAndroid.jar
120 | fi
121 |
122 | if [ ! -r "${shrinkedAndroidJar}" ]; then
123 | shrinkedAndroidJar=${libdir}/${shrinkedAndroidJar}
124 | fi
125 |
126 | if [ ! -r "${shrinkedAndroidJar}" ]; then
127 | echo `basename "$prog"`": can't find shrinkedAndroid.jar" 1>&2
128 | exit 1
129 | fi
130 |
131 | if [ "$OSTYPE" = "cygwin" ]; then
132 | # For Cygwin, convert the jarfile path into native Windows style.
133 | jarpath=`cygpath -w "$libdir/$jarfile"`
134 | proguard=`cygpath -w "${proguard}"`
135 | shrinkedAndroidJar=`cygpath -w "${shrinkedAndroidJar}"`
136 | else
137 | jarpath="$libdir/$jarfile"
138 | fi
139 |
140 | if expr "x$1" : 'x--output' >/dev/null; then
141 | exec 1>$2
142 | shift 2
143 | fi
144 |
145 | if [ $# -ne 1 ]; then
146 | echo "Usage : $0 [--output