Full Code of jinyb09017/delayActionDemo for AI

master 0ce4c6c9cb5f cached
46 files
43.2 KB
12.6k tokens
77 symbols
1 requests
Download .txt
Repository: jinyb09017/delayActionDemo
Branch: master
Commit: 0ce4c6c9cb5f
Files: 46
Total size: 43.2 KB

Directory structure:
gitextract_ayo7h9er/

├── .gitignore
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── goodluck/
│       │               └── abbott/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── goodluck/
│       │   │           └── abbott/
│       │   │               ├── DiscountActivity.java
│       │   │               ├── LoginActivity.java
│       │   │               ├── MainActivity.java
│       │   │               ├── OrderDetailActivity.java
│       │   │               ├── UserConfigCache.java
│       │   │               └── valid/
│       │   │                   ├── DiscountValid.java
│       │   │                   ├── LoginValid.java
│       │   │                   └── RightValid.java
│       │   └── res/
│       │       ├── layout/
│       │       │   ├── activity_discount_activivty.xml
│       │       │   ├── activity_login_activivty.xml
│       │       │   ├── activity_main.xml
│       │       │   └── activity_order_detail.xml
│       │       └── values/
│       │           ├── colors.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── goodluck/
│                       └── abbott/
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── libaction/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── toptechs/
│       │               └── libaction/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── toptechs/
│       │   │           └── libaction/
│       │   │               ├── MainActivity.java
│       │   │               ├── action/
│       │   │               │   ├── Action.java
│       │   │               │   ├── ActionManager.java
│       │   │               │   ├── CallUnit.java
│       │   │               │   ├── SingleCall.java
│       │   │               │   └── Valid.java
│       │   │               ├── annotation/
│       │   │               │   └── Interceptor.java
│       │   │               └── exp/
│       │   │                   └── ValidException.java
│       │   └── res/
│       │       ├── layout/
│       │       │   └── activity_main.xml
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── toptechs/
│                       └── libaction/
│                           └── ExampleUnitTest.java
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/dictionaries
.idea/libraries

# Keystore files
# Uncomment the following line if you do not want to check your keystore files in.
#*.jks

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild

# Google Services (e.g. APIs or Firebase)
google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json


# 补充的内容
*.iws
.idea/


================================================
FILE: README.md
================================================
### 如何延迟执行目标行为

例如我们有时候会有这样的需求,那就是在执行目标行为时候,需要执行前置的一些行为。而这些前置行为,需要用户参与才能完成,或者这些前置
行为要跳转到另外一个未知上下文中执行。

典型应用场景:

![](./screen/delay_action.png)


那么我们如何实现这种需求呢?请教参我的博客分析[android 登录成功后再跳转到目标界面的思考](http://www.jianshu.com/p/1d0180ec64fb)



### 添加依赖

```
compile 'com.abbott.delayaction:libaction:1.0.1'

```



### 1、基本执行流程图如下

![](http://upload-images.jianshu.io/upload_images/2159256-91dedfb30a1c140c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700)

### 2、演示图如下

只需要进行登录的验证

![](./screen/action-login.gif)

需同时进行登录和优惠券的验证

![](./screen/action-login-dis.gif)

### 3、代码调用如下

调用目标方法
```

 SingleCall.getInstance()
                        .addAction(MainActivity.this)
                        .addValid(new LoginValid(MainActivity.this))
                        .addValid(new DiscountValid(MainActivity.this))
                        .doCall();

```

完成valid检验后,再执行即可。
```
SingleCall.getInstance().doCall();

```

当然每个对应的验证模型需要自己去完成,例如LoginValid的模型

```
package com.goodluck.abbott.valid;

import android.app.Activity;
import android.content.Context;

import com.goodluck.abbott.LoginActivity;
import com.goodluck.abbott.UserConfigCache;
import com.toptechs.libaction.action.Valid;

/**
 * Created by jinyabo on 8/12/2017.
 */

public class LoginValid implements Valid {
    private Context context;

    public LoginValid(Context context) {
        this.context = context;
    }

    /**
     * check whether it login in or not
     * @return
     */
    @Override
    public boolean check() {
        return UserConfigCache.isLogin(context);
    }


    /**
     * if check() return false. then doValid was called
     */
    @Override
    public void doValid() {
         LoginActivity.start((Activity) context);
    }
}
```





================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.goodluck.action"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile project(':libaction')
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/zhangfei/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: app/src/androidTest/java/com/goodluck/abbott/ExampleInstrumentedTest.java
================================================
package com.goodluck.abbott;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.goodluck.Interceptor", appContext.getPackageName());
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.goodluck.abbott">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".LoginActivity" />
        <activity android:name=".OrderDetailActivity"></activity>
        <activity android:name=".DiscountActivity"></activity>
    </application>

</manifest>

================================================
FILE: app/src/main/java/com/goodluck/abbott/DiscountActivity.java
================================================
package com.goodluck.abbott;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.toptechs.libaction.action.SingleCall;

/**
 * get discount
 */

public class DiscountActivity extends AppCompatActivity {
    public static final int REQUEST_CODE_LOGIN = 1000;

    public static void startActivityForResult(Activity activity, int requestCode) {
        Intent intent = new Intent(activity, DiscountActivity.class);
        activity.startActivityForResult(intent, requestCode);
    }

    public static void start(Activity activity) {
        Intent intent = new Intent(activity, DiscountActivity.class);
        activity.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_discount_activivty);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                UserConfigCache.setDiscount(DiscountActivity.this, true);

                //这里继续
                SingleCall.getInstance().doCall();

                finish();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}


================================================
FILE: app/src/main/java/com/goodluck/abbott/LoginActivity.java
================================================
package com.goodluck.abbott;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

import com.toptechs.libaction.action.SingleCall;


public class LoginActivity extends AppCompatActivity {
    public static final int REQUEST_CODE_LOGIN = 1000;

    public static void startActivityForResult(Activity activity, int requestCode) {
        Intent intent = new Intent(activity, LoginActivity.class);
        activity.startActivityForResult(intent, requestCode);
    }

    public static void start(Activity activity) {
        Intent intent = new Intent(activity, LoginActivity.class);
        activity.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login_activivty);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(LoginActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
                UserConfigCache.setLogin(LoginActivity.this, true);
                //这里继续
                SingleCall.getInstance().doCall();
                finish();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}


================================================
FILE: app/src/main/java/com/goodluck/abbott/MainActivity.java
================================================
package com.goodluck.abbott;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.goodluck.abbott.valid.DiscountValid;
import com.goodluck.abbott.valid.LoginValid;
import com.toptechs.libaction.action.Action;
import com.toptechs.libaction.action.SingleCall;

public class MainActivity extends AppCompatActivity implements Action {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                SingleCall.getInstance()
                        .addAction(MainActivity.this)
                        .addValid(new LoginValid(MainActivity.this))
                        .doCall();


            }
        });

        findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {



                SingleCall.getInstance()
                        .addAction(MainActivity.this)
                        .addValid(new LoginValid(MainActivity.this))
                        .addValid(new DiscountValid(MainActivity.this))
                        .doCall();

            }
        });

        findViewById(R.id.logout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UserConfigCache.setLogin(MainActivity.this, false);


            }
        });
        findViewById(R.id.logoutDis).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UserConfigCache.setDiscount(MainActivity.this, false);
            }
        });
    }


    @Override
    public void call() {
        OrderDetailActivity.startActivity(MainActivity.this, "1234");
    }
}


================================================
FILE: app/src/main/java/com/goodluck/abbott/OrderDetailActivity.java
================================================
package com.goodluck.abbott;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class OrderDetailActivity extends AppCompatActivity {
    private static final String EXTRA_ORDER_ID = "orderId";

    private TextView mOrderInfoText;
    private String mOrderId;




    @Override
    protected void onStart() {
        super.onStart();

    }

    public static void startActivity(Context context, String orderId) {
        Intent intent = new Intent(context, OrderDetailActivity.class);
        intent.putExtra(EXTRA_ORDER_ID, orderId);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_order_detail);

        mOrderId = getIntent().getStringExtra(EXTRA_ORDER_ID);
        mOrderInfoText = (TextView) findViewById(R.id.orderInfo);
    }



}


================================================
FILE: app/src/main/java/com/goodluck/abbott/UserConfigCache.java
================================================
package com.goodluck.abbott;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created by zhangfei on 2017/3/31.
 */

public class UserConfigCache {
    private static final String PREFERENCE_FILE = "user_config_cache";

    private static SharedPreferences getPreference(Context context){
        return context.getSharedPreferences(PREFERENCE_FILE, Context.MODE_PRIVATE);
    }

    private static final String IS_LOGIN = "is_login";
    private static final String DISCOUNT = "discount";//折扣

    public static boolean isLogin(Context context){
        return getPreference(context).getBoolean(IS_LOGIN, false);
    }
    public static void setLogin(Context context, boolean logged) {
        getPreference(context).edit().putBoolean(IS_LOGIN, logged).apply();
    }


    public static boolean isDiscount(Context context){
        return getPreference(context).getBoolean(DISCOUNT, false);
    }
    public static void setDiscount(Context context, boolean dis) {
        getPreference(context).edit().putBoolean(DISCOUNT, dis).apply();
    }

}


================================================
FILE: app/src/main/java/com/goodluck/abbott/valid/DiscountValid.java
================================================
package com.goodluck.abbott.valid;

import android.app.Activity;
import android.content.Context;

import com.goodluck.abbott.DiscountActivity;
import com.goodluck.abbott.UserConfigCache;
import com.toptechs.libaction.action.Valid;

/**
 * Created by jinyabo on 8/12/2017.
 */

public class DiscountValid implements Valid {
    private Context context;

    public DiscountValid(Context context) {
        this.context = context;
    }

    /**
     *
     * @return
     */
    @Override
    public boolean check() {
        return UserConfigCache.isDiscount(context);
    }


    /**
     * if check() return false. then doValid was called
     */
    @Override
    public void doValid() {
         DiscountActivity.start((Activity) context);
    }
}


================================================
FILE: app/src/main/java/com/goodluck/abbott/valid/LoginValid.java
================================================
package com.goodluck.abbott.valid;

import android.app.Activity;
import android.content.Context;

import com.goodluck.abbott.LoginActivity;
import com.goodluck.abbott.UserConfigCache;
import com.toptechs.libaction.action.Valid;

/**
 * Created by jinyabo on 8/12/2017.
 */

public class LoginValid implements Valid {
    private Context context;

    public LoginValid(Context context) {
        this.context = context;
    }

    /**
     * check whether it login in or not
     * @return
     */
    @Override
    public boolean check() {
        return UserConfigCache.isLogin(context);
    }


    /**
     * if check() return false. then doValid was called
     */
    @Override
    public void doValid() {
         LoginActivity.start((Activity) context);
    }
}


================================================
FILE: app/src/main/java/com/goodluck/abbott/valid/RightValid.java
================================================
package com.goodluck.abbott.valid;

import android.content.Context;
import android.widget.Toast;

import com.toptechs.libaction.action.ActionManager;
import com.toptechs.libaction.action.Valid;


/**
 * Created by jinyabo on 8/12/2017.
 *
 * 根据传入的数据,判断是否的对应界面的权限操作。
 */

public class RightValid implements Valid {

    String right;
    String page;
    Context context;

    public RightValid(Context context, String right, String page) {
        this.right = right;
        this.page = page;
        this.context = context;
    }

    @Override
    public boolean check() {
        if(right.equals("2") && page.equals("order")){
            return true;
        }
        return false;
    }

    @Override
    public void doValid() {
        Toast.makeText(context, String.format("没有%s界面的权限",page),Toast.LENGTH_SHORT).show();
        right = "2";
        page = "order";

        Toast.makeText(context, String.format("获得%s界面的权限",page),Toast.LENGTH_SHORT).show();
        ActionManager.instance().checkValid();
    }
}


================================================
FILE: app/src/main/res/layout/activity_discount_activivty.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is discount activity." />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="get discount" />
</LinearLayout>


================================================
FILE: app/src/main/res/layout/activity_login_activivty.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is login activity." />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="登录" />
</LinearLayout>


================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context="com.goodluck.abbott.MainActivity">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是订单详情页入口" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="打开订单(登录)"
        android:textSize="20sp" />


    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="打开订单详情(登录 and 优惠)"
        android:textSize="20sp" />

    <Button
        android:id="@+id/logout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="退出登录状态"
        android:textSize="20sp" />

    <Button
        android:id="@+id/logoutDis"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="退出优惠状态"
        android:textSize="20sp" />

</LinearLayout>


================================================
FILE: app/src/main/res/layout/activity_order_detail.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.goodluck.abbott.OrderDetailActivity">

    <TextView
        android:id="@+id/orderInfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="This is order detail page"
        android:textSize="30sp" />
</RelativeLayout>


================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">delayAction</string>
</resources>


================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: app/src/test/java/com/goodluck/abbott/ExampleUnitTest.java
================================================
package com.goodluck.abbott;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
        //比1.2版本多一个gradle字样
        classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'

    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Fri Dec 08 17:48:34 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip


================================================
FILE: gradle.properties
================================================
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Fri Dec 08 17:48:26 CST 2017
#systemProp.http.proxyHost=127.0.0.1
org.gradle.jvmargs=-Xmx1536m
#systemProp.http.proxyPort=1080


================================================
FILE: gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: libaction/.gitignore
================================================
/build


================================================
FILE: libaction/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
}


def siteUrl = 'https://github.com/jinyb09017/delayActionDemo'      // 项目的主页
def gitUrl = 'https://github.com/jinyb09017/delayActionDemo.git'   // Git仓库的url
group = "com.abbott.delayaction"                                        // Maven Group ID for the artifact,一般填你唯一的包名
version = "1.0.1"
install {
    repositories.mavenInstaller {
        // This generates POM.xml with proper parameters
        pom {
            project {
                packaging 'aar'
                // Add your description here
                description 'target method delay'
                name 'libaction' 	//项目描述
                url siteUrl
                // Set your license
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id 'jinyb'		//填写的一些基本信息
                        name 'jinyabo'
                        email 'jyb_96@sina.com'
                    }
                }
                scm {
                    connection gitUrl
                    developerConnection gitUrl
                    url siteUrl
                }
            }
        }
    }
}
task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}
task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}
//解决doc报错问题
tasks.withType(Javadoc) {
    options.addStringOption('Xdoclint:none', '-quiet')
    options.addStringOption('encoding', 'UTF-8')
    options.addStringOption('charSet', 'UTF-8')
}

artifacts {
    archives sourcesJar
//    archives sourcesJar
}

//对于support依赖生成doc的解决的方案
android.libraryVariants.all { variant ->
    println variant.javaCompile.classpath.files
    if(variant.name == 'release') { //我们只需 release 的 javadoc
        task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) {
            // title = ''
            // description = ''
            source = variant.javaCompile.source
            classpath = files(variant.javaCompile.classpath.files, project.android.getBootClasspath())
            options {
                encoding "utf-8"
                links "http://docs.oracle.com/javase/7/docs/api/"
                linksOffline "http://d.android.com/reference", "${android.sdkDirectory}/docs/reference"

            }

            exclude '**/BuildConfig.java'
            exclude '**/R.java'
        }
        task("javadoc${variant.name.capitalize()}Jar", type: Jar, dependsOn: "generate${variant.name.capitalize()}Javadoc") {
            classifier = 'javadoc'
            from tasks.getByName("generate${variant.name.capitalize()}Javadoc").destinationDir

        }
        artifacts {
            archives tasks.getByName("javadoc${variant.name.capitalize()}Jar")
        }
    }
}



Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")
    configurations = ['archives']
    pkg {
        repo = "maven"
        name = "delayaction"	//发布到JCenter上的项目名字
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        licenses = ["Apache-2.0"]
        publish = true
    }
}

//请进入指定目录进行操作
//gradle install
//gradle install -xjavadoc
//gradle bintrayUpload

================================================
FILE: libaction/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/jinyabo/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: libaction/src/androidTest/java/com/toptechs/libaction/ExampleInstrumentedTest.java
================================================
package com.toptechs.libaction;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumentation test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.toptechs.libaction.test", appContext.getPackageName());
    }
}


================================================
FILE: libaction/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.toptechs.libaction">


    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />


    <!--ava?--> <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".MainActivity"></activity>
    </application>

</manifest>

================================================
FILE: libaction/src/main/java/com/toptechs/libaction/MainActivity.java
================================================
package com.toptechs.libaction;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/action/Action.java
================================================
package com.toptechs.libaction.action;

/**
 * Created by jinyabo on 8/12/2017.
 */

public interface Action {
    void call();
}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/action/ActionManager.java
================================================
package com.toptechs.libaction.action;


import com.toptechs.libaction.annotation.Interceptor;
import com.toptechs.libaction.exp.ValidException;

import java.lang.reflect.Method;
import java.util.Queue;
import java.util.Stack;

/**
 * Created by jinyabo on 8/12/2017.
 */


@Deprecated
public class ActionManager {

    static ActionManager instance = new ActionManager();

    public static ActionManager instance() {

        return instance;
    }

    Stack<CallUnit> delaysActions = new Stack<>();

    /**
     * 根据条件判断,是否要执行一个action
     *
     * @param callUnit
     */
    public void postCallUnit(CallUnit callUnit) {

        //清除所有的actions
        delaysActions.clear();
        //执行check
        callUnit.check();
        //如果全部满足,则直接跳转目标方法
        if (callUnit.getValidQueue().size() == 0) {
            callUnit.getAction().call();
        } else {
            //加入到延迟执行体中来
            delaysActions.push(callUnit);

            Valid valid = callUnit.getValidQueue().peek();
            callUnit.setLastValid(valid);
            //是否会有后置任务
            valid.doValid();

        }
    }


    /**
     * 通过反射注解来组装(但是这个前提是无参的构造方法才行)
     *
     * @param action
     */
    public void postCallUnit(Action action) {
        Class clz = action.getClass();
        try {
            Method method = clz.getMethod("call");
            Interceptor interceptor = method.getAnnotation(Interceptor.class);
            Class<? extends Valid>[] clzArray = interceptor.value();
            CallUnit callUnit = new CallUnit(action);
            for (Class cla : clzArray) {
                callUnit.addValid((Valid) cla.newInstance());
            }

            postCallUnit(callUnit);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * 重新检查
     */
    public void checkValid() {

        if (delaysActions.size() > 0) {
            CallUnit callUnit = delaysActions.peek();

            if (callUnit.getLastValid().check() == false) {
                throw new ValidException(String.format("you must pass through the %s,and then reCall()", callUnit.getLastValid().getClass().toString()));

            }

            if (callUnit != null) {
                Queue<Valid> validQueue = callUnit.getValidQueue();

                validQueue.remove(callUnit.getLastValid());
                //valid已经执行完了,则表示此delay已经检验完了--执行目标方法
                if (validQueue.size() == 0) {
                    callUnit.getAction().call();
                    //把这个任务移出
                    delaysActions.remove(callUnit);
                } else {

                    Valid valid = callUnit.getValidQueue().peek();
                    callUnit.setLastValid(valid);
                    //是否会有后置任务
                    valid.doValid();
                }
            }
        }
    }



}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/action/CallUnit.java
================================================
package com.toptechs.libaction.action;

import java.util.ArrayDeque;
import java.util.Queue;

/**
 * Created by jinyabo on 8/12/2017.
 */

/**
 * 一个执行单元。
 * 包括一个执行目标体和一个检验队列。检验队列用来保证所有的前置条件。当所有的前置条件都通过后,才能进行执行单元。
 */
public class CallUnit {
    //目标行为
    private Action action;
    //先进先出验证模型
    private Queue<Valid> validQueue = new ArrayDeque<>();
    //上一个执行的valid
    private Valid lastValid;


    public Valid getLastValid() {
        return lastValid;
    }

    public void setLastValid(Valid lastValid) {
        this.lastValid = lastValid;
    }

    public Action getAction() {
        return action;
    }

    public void setAction(Action action) {
        this.action = action;
    }


    public CallUnit() {
    }

    public CallUnit(Action action) {
        this.action = action;
    }

    public static CallUnit newInstance(Action action){
        return new CallUnit(action);
    }

    public CallUnit addValid(Valid valid) {
        validQueue.add(valid);
        return this;
    }

    public Queue<Valid> getValidQueue() {
        return validQueue;
    }

    //检查valid.如果已经满足要求,则移出来队列
    public void check() {
        for (Valid valid : validQueue) {
            if (valid.check()) {
                validQueue.remove(valid);
            }
        }
    }

    /**
     * start
     */
    public void doCall(){
        ActionManager.instance().postCallUnit(this);
    }


}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/action/SingleCall.java
================================================
package com.toptechs.libaction.action;

/**
 * Created by jinyabo on 13/12/2017.
 *
 * 如果CallUnit验证模型中没有嵌套的验证模型,则可以直接使用SingleCall即可
 */

public class SingleCall {

    CallUnit callUnit = new CallUnit();

    public SingleCall addAction(Action action){
        clear();
        callUnit.setAction(action);
        return this;
    }


    public SingleCall addValid(Valid valid){
        //只添加无效的,验证不通过的。
        if(valid.check()){
            return this;
        }
        callUnit.addValid(valid);
        return this;
    }

    public void doCall(){

        //如果上一条valid难没有通过,是不允许再发起call的
        if(callUnit.getLastValid() != null && !callUnit.getLastValid().check() ){
            return;
        }

        //执行action
        if(callUnit.getValidQueue().size() == 0 && callUnit.getAction() != null){
            callUnit.getAction().call();
            //清空
            clear();
        }else{
            //执行验证。
            Valid valid = callUnit.getValidQueue().poll();
            callUnit.setLastValid(valid);
            valid.doValid();
        }

    }

    public void clear(){
        callUnit.getValidQueue().clear();
        callUnit.setAction(null);
        callUnit.setLastValid(null);
    }


    // 单一全局访问点
    public static SingleCall getInstance() {
        return SingletonHolder.mInstance;
    }

    // 静态内部类,第一次加载Singleton类时不会初始化mInstance,
    // 当调用getInstance()时才会初始化
    private static class SingletonHolder {
        private static SingleCall mInstance = new SingleCall();
    }
}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/action/Valid.java
================================================
package com.toptechs.libaction.action;

/**
 * Created by jinyabo on 8/12/2017.
 */

public interface Valid {

    /**
     * 是否满足检验器的要求,如果不满足的话,则执行doAction方法。如果满足,则执行目标action
     * @return
     */
    boolean check();

    void doValid();
}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/annotation/Interceptor.java
================================================
package com.toptechs.libaction.annotation;


import com.toptechs.libaction.action.Valid;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 这里只能用于无参数的valid模型。
 */


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Interceptor {

    Class<? extends Valid>[] value() default {};

}


================================================
FILE: libaction/src/main/java/com/toptechs/libaction/exp/ValidException.java
================================================
package com.toptechs.libaction.exp;

/**
 * Created by jinyabo on 10/12/2017.
 */

public class ValidException extends RuntimeException {

    public ValidException() {
    }

    public ValidException(String message) {
        super(message);
    }
}


================================================
FILE: libaction/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.toptechs.libaction.MainActivity">

</android.support.constraint.ConstraintLayout>


================================================
FILE: libaction/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">LibAction</string>
</resources>


================================================
FILE: libaction/src/test/java/com/toptechs/libaction/ExampleUnitTest.java
================================================
package com.toptechs.libaction;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: settings.gradle
================================================
rootProject.name = "delayActionDemo"
include ':app', ':libaction'
Download .txt
gitextract_ayo7h9er/

├── .gitignore
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── goodluck/
│       │               └── abbott/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── goodluck/
│       │   │           └── abbott/
│       │   │               ├── DiscountActivity.java
│       │   │               ├── LoginActivity.java
│       │   │               ├── MainActivity.java
│       │   │               ├── OrderDetailActivity.java
│       │   │               ├── UserConfigCache.java
│       │   │               └── valid/
│       │   │                   ├── DiscountValid.java
│       │   │                   ├── LoginValid.java
│       │   │                   └── RightValid.java
│       │   └── res/
│       │       ├── layout/
│       │       │   ├── activity_discount_activivty.xml
│       │       │   ├── activity_login_activivty.xml
│       │       │   ├── activity_main.xml
│       │       │   └── activity_order_detail.xml
│       │       └── values/
│       │           ├── colors.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── goodluck/
│                       └── abbott/
│                           └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── libaction/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── toptechs/
│       │               └── libaction/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── toptechs/
│       │   │           └── libaction/
│       │   │               ├── MainActivity.java
│       │   │               ├── action/
│       │   │               │   ├── Action.java
│       │   │               │   ├── ActionManager.java
│       │   │               │   ├── CallUnit.java
│       │   │               │   ├── SingleCall.java
│       │   │               │   └── Valid.java
│       │   │               ├── annotation/
│       │   │               │   └── Interceptor.java
│       │   │               └── exp/
│       │   │                   └── ValidException.java
│       │   └── res/
│       │       ├── layout/
│       │       │   └── activity_main.xml
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── toptechs/
│                       └── libaction/
│                           └── ExampleUnitTest.java
└── settings.gradle
Download .txt
SYMBOL INDEX (77 symbols across 19 files)

FILE: app/src/androidTest/java/com/goodluck/abbott/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: app/src/main/java/com/goodluck/abbott/DiscountActivity.java
  class DiscountActivity (line 15) | public class DiscountActivity extends AppCompatActivity {
    method startActivityForResult (line 18) | public static void startActivityForResult(Activity activity, int reque...
    method start (line 23) | public static void start(Activity activity) {
    method onCreate (line 28) | @Override
    method onDestroy (line 46) | @Override

FILE: app/src/main/java/com/goodluck/abbott/LoginActivity.java
  class LoginActivity (line 13) | public class LoginActivity extends AppCompatActivity {
    method startActivityForResult (line 16) | public static void startActivityForResult(Activity activity, int reque...
    method start (line 21) | public static void start(Activity activity) {
    method onCreate (line 26) | @Override
    method onDestroy (line 42) | @Override

FILE: app/src/main/java/com/goodluck/abbott/MainActivity.java
  class MainActivity (line 12) | public class MainActivity extends AppCompatActivity implements Action {
    method onCreate (line 14) | @Override
    method call (line 66) | @Override

FILE: app/src/main/java/com/goodluck/abbott/OrderDetailActivity.java
  class OrderDetailActivity (line 9) | public class OrderDetailActivity extends AppCompatActivity {
    method onStart (line 18) | @Override
    method startActivity (line 24) | public static void startActivity(Context context, String orderId) {
    method onCreate (line 30) | @Override

FILE: app/src/main/java/com/goodluck/abbott/UserConfigCache.java
  class UserConfigCache (line 10) | public class UserConfigCache {
    method getPreference (line 13) | private static SharedPreferences getPreference(Context context){
    method isLogin (line 20) | public static boolean isLogin(Context context){
    method setLogin (line 23) | public static void setLogin(Context context, boolean logged) {
    method isDiscount (line 28) | public static boolean isDiscount(Context context){
    method setDiscount (line 31) | public static void setDiscount(Context context, boolean dis) {

FILE: app/src/main/java/com/goodluck/abbott/valid/DiscountValid.java
  class DiscountValid (line 14) | public class DiscountValid implements Valid {
    method DiscountValid (line 17) | public DiscountValid(Context context) {
    method check (line 25) | @Override
    method doValid (line 34) | @Override

FILE: app/src/main/java/com/goodluck/abbott/valid/LoginValid.java
  class LoginValid (line 14) | public class LoginValid implements Valid {
    method LoginValid (line 17) | public LoginValid(Context context) {
    method check (line 25) | @Override
    method doValid (line 34) | @Override

FILE: app/src/main/java/com/goodluck/abbott/valid/RightValid.java
  class RightValid (line 16) | public class RightValid implements Valid {
    method RightValid (line 22) | public RightValid(Context context, String right, String page) {
    method check (line 28) | @Override
    method doValid (line 36) | @Override

FILE: app/src/test/java/com/goodluck/abbott/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test

FILE: libaction/src/androidTest/java/com/toptechs/libaction/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: libaction/src/main/java/com/toptechs/libaction/MainActivity.java
  class MainActivity (line 6) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 8) | @Override

FILE: libaction/src/main/java/com/toptechs/libaction/action/Action.java
  type Action (line 7) | public interface Action {
    method call (line 8) | void call();

FILE: libaction/src/main/java/com/toptechs/libaction/action/ActionManager.java
  class ActionManager (line 16) | @Deprecated
    method instance (line 21) | public static ActionManager instance() {
    method postCallUnit (line 33) | public void postCallUnit(CallUnit callUnit) {
    method postCallUnit (line 60) | public void postCallUnit(Action action) {
    method checkValid (line 85) | public void checkValid() {

FILE: libaction/src/main/java/com/toptechs/libaction/action/CallUnit.java
  class CallUnit (line 14) | public class CallUnit {
    method getLastValid (line 23) | public Valid getLastValid() {
    method setLastValid (line 27) | public void setLastValid(Valid lastValid) {
    method getAction (line 31) | public Action getAction() {
    method setAction (line 35) | public void setAction(Action action) {
    method CallUnit (line 40) | public CallUnit() {
    method CallUnit (line 43) | public CallUnit(Action action) {
    method newInstance (line 47) | public static CallUnit newInstance(Action action){
    method addValid (line 51) | public CallUnit addValid(Valid valid) {
    method getValidQueue (line 56) | public Queue<Valid> getValidQueue() {
    method check (line 61) | public void check() {
    method doCall (line 72) | public void doCall(){

FILE: libaction/src/main/java/com/toptechs/libaction/action/SingleCall.java
  class SingleCall (line 9) | public class SingleCall {
    method addAction (line 13) | public SingleCall addAction(Action action){
    method addValid (line 20) | public SingleCall addValid(Valid valid){
    method doCall (line 29) | public void doCall(){
    method clear (line 50) | public void clear(){
    method getInstance (line 58) | public static SingleCall getInstance() {
    class SingletonHolder (line 64) | private static class SingletonHolder {

FILE: libaction/src/main/java/com/toptechs/libaction/action/Valid.java
  type Valid (line 7) | public interface Valid {
    method check (line 13) | boolean check();
    method doValid (line 15) | void doValid();

FILE: libaction/src/main/java/com/toptechs/libaction/exp/ValidException.java
  class ValidException (line 7) | public class ValidException extends RuntimeException {
    method ValidException (line 9) | public ValidException() {
    method ValidException (line 12) | public ValidException(String message) {

FILE: libaction/src/test/java/com/toptechs/libaction/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test
Condensed preview — 46 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (51K chars).
[
  {
    "path": ".gitignore",
    "chars": 867,
    "preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated file"
  },
  {
    "path": "README.md",
    "chars": 1733,
    "preview": "### 如何延迟执行目标行为\n\n例如我们有时候会有这样的需求,那就是在执行目标行为时候,需要执行前置的一些行为。而这些前置行为,需要用户参与才能完成,或者这些前置\n行为要跳转到另外一个未知上下文中执行。\n\n典型应用场景:\n\n![](./sc"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 970,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 25\n    buildToolsVersion \"25.0.2\"\n    defaultCo"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 937,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "app/src/androidTest/java/com/goodluck/abbott/ExampleInstrumentedTest.java",
    "chars": 747,
    "preview": "package com.goodluck.abbott;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimpor"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 893,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/DiscountActivity.java",
    "chars": 1387,
    "preview": "package com.goodluck.abbott;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.Bundle;\nimpo"
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/LoginActivity.java",
    "chars": 1456,
    "preview": "package com.goodluck.abbott;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.Bundle;\nimpo"
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/MainActivity.java",
    "chars": 1996,
    "preview": "package com.goodluck.abbott;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android."
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/OrderDetailActivity.java",
    "chars": 1023,
    "preview": "package com.goodluck.abbott;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\ni"
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/UserConfigCache.java",
    "chars": 1082,
    "preview": "package com.goodluck.abbott;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\n\n/**\n * Created "
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/valid/DiscountValid.java",
    "chars": 752,
    "preview": "package com.goodluck.abbott.valid;\n\nimport android.app.Activity;\nimport android.content.Context;\n\nimport com.goodluck.ab"
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/valid/LoginValid.java",
    "chars": 770,
    "preview": "package com.goodluck.abbott.valid;\n\nimport android.app.Activity;\nimport android.content.Context;\n\nimport com.goodluck.ab"
  },
  {
    "path": "app/src/main/java/com/goodluck/abbott/valid/RightValid.java",
    "chars": 1022,
    "preview": "package com.goodluck.abbott.valid;\n\nimport android.content.Context;\nimport android.widget.Toast;\n\nimport com.toptechs.li"
  },
  {
    "path": "app/src/main/res/layout/activity_discount_activivty.xml",
    "chars": 645,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/activity_login_activivty.xml",
    "chars": 632,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 1498,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_order_detail.xml",
    "chars": 594,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 74,
    "preview": "<resources>\n    <string name=\"app_name\">delayAction</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "app/src/test/java/com/goodluck/abbott/ExampleUnitTest.java",
    "chars": 397,
    "preview": "package com.goodluck.abbott;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test,"
  },
  {
    "path": "build.gradle",
    "chars": 673,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Fri Dec 08 17:48:34 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 851,
    "preview": "## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.grad"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "libaction/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "libaction/build.gradle",
    "chars": 4667,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'com.github.dcendents.android-maven'\napply plugin: 'com.jfrog.bintray'"
  },
  {
    "path": "libaction/proguard-rules.pro",
    "chars": 936,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "libaction/src/androidTest/java/com/toptechs/libaction/ExampleInstrumentedTest.java",
    "chars": 753,
    "preview": "package com.toptechs.libaction;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nim"
  },
  {
    "path": "libaction/src/main/AndroidManifest.xml",
    "chars": 533,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/MainActivity.java",
    "chars": 335,
    "preview": "package com.toptechs.libaction;\n\nimport android.support.v7.app.AppCompatActivity;\nimport android.os.Bundle;\n\npublic clas"
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/action/Action.java",
    "chars": 130,
    "preview": "package com.toptechs.libaction.action;\n\n/**\n * Created by jinyabo on 8/12/2017.\n */\n\npublic interface Action {\n    void "
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/action/ActionManager.java",
    "chars": 2985,
    "preview": "package com.toptechs.libaction.action;\n\n\nimport com.toptechs.libaction.annotation.Interceptor;\nimport com.toptechs.libac"
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/action/CallUnit.java",
    "chars": 1406,
    "preview": "package com.toptechs.libaction.action;\n\nimport java.util.ArrayDeque;\nimport java.util.Queue;\n\n/**\n * Created by jinyabo "
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/action/SingleCall.java",
    "chars": 1516,
    "preview": "package com.toptechs.libaction.action;\n\n/**\n * Created by jinyabo on 13/12/2017.\n *\n * 如果CallUnit验证模型中没有嵌套的验证模型,则可以直接使用S"
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/action/Valid.java",
    "chars": 243,
    "preview": "package com.toptechs.libaction.action;\n\n/**\n * Created by jinyabo on 8/12/2017.\n */\n\npublic interface Valid {\n\n    /**\n "
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/annotation/Interceptor.java",
    "chars": 433,
    "preview": "package com.toptechs.libaction.annotation;\n\n\nimport com.toptechs.libaction.action.Valid;\n\nimport java.lang.annotation.El"
  },
  {
    "path": "libaction/src/main/java/com/toptechs/libaction/exp/ValidException.java",
    "chars": 252,
    "preview": "package com.toptechs.libaction.exp;\n\n/**\n * Created by jinyabo on 10/12/2017.\n */\n\npublic class ValidException extends R"
  },
  {
    "path": "libaction/src/main/res/layout/activity_main.xml",
    "chars": 436,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
  },
  {
    "path": "libaction/src/main/res/values/strings.xml",
    "chars": 72,
    "preview": "<resources>\n    <string name=\"app_name\">LibAction</string>\n</resources>\n"
  },
  {
    "path": "libaction/src/test/java/com/toptechs/libaction/ExampleUnitTest.java",
    "chars": 400,
    "preview": "package com.toptechs.libaction;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit te"
  },
  {
    "path": "settings.gradle",
    "chars": 66,
    "preview": "rootProject.name = \"delayActionDemo\"\ninclude ':app', ':libaction'\n"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the jinyb09017/delayActionDemo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 46 files (43.2 KB), approximately 12.6k tokens, and a symbol index with 77 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!