diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e12f17f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Built application files +*.apk +*.ap_ + +# Files for the Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ +/*/build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# IDEA Files +.idea +*.iml +/*.ipr +/*.iws + +# Eclipse Files +/target +*.classpath +*.project +*.settings + +app/src/main/res/values/config.xml +app/src/main/res/drawable/yw_1222.jpg + +# OS X Files +.DS_Store + +map.txt diff --git a/README.md b/README.md index 574a3822..45c3b089 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ 4. Generate mapping-relationship document automatically. #### Ⅲ. The Basic -1. Add dependencies +1. Add dependencies and configuration apply plugin: 'com.neenbedankt.android-apt' @@ -38,9 +38,15 @@ } } + apt { + arguments { + moduleName project.getName(); + } + } + dependencies { - apt 'com.alibaba.android:arouter-compiler:x.x.x' - compile 'com.alibaba.android:arouter-api:x.x.x' + apt 'com.alibaba:arouter-compiler:x.x.x' + compile 'com.alibaba:arouter-api:x.x.x' ... } @@ -284,6 +290,12 @@ 2. 注意:推荐使用ByName方式获取Service,ByType这种方式写起来比较方便,但如果存在多实现的情况时,SDK不保证能获取到你想要的实现 +10. Service management - resolve dependencies through services + + 可以通过ARouter service包装您的业务逻辑或者sdk,在service的init方法中初始化您的sdk,不同的sdk使用ARouter的service进行调用, + 每一个service在第一次使用的时候会被初始化,即调用init方法。 + 这样就可以告别各种乱七八糟的依赖关系的梳理,只要能调用到这个service,那么这个service中所包含的sdk等就已经被初始化过了,完全不需要 + 关心各个sdk的初始化顺序。 #### Ⅴ. More function @@ -347,15 +359,4 @@ - They need to implement different interface - Interceptors will take effect in every navigation. Interceptors will initialize asynchronously at initialization of ARouter. If the initialization is not finished yet when first navigation execute, the navigation will block and wait. - - Services will do the initialization only when they are invoked. If a service has never been invoked in whole lifecycle, it won’t initialize. - -3. Support Jack-Complier tool chain - - - ARouter hide the messy params handling dependent on some javac APIs. As a result, when you use Jack to compile your project, some special work is needed. - - // 在使用了Jack的模块的build.gradle中加入如下参数即可,moduleName保证和其他模块不重复,使用标准字符,不要使用各种特殊字符 - apt { - arguments { - moduleName 'lalala' - } - } + - Services will do the initialization only when they are invoked. If a service has never been invoked in whole lifecycle, it won’t initialize. \ No newline at end of file diff --git a/README_CN.md b/README_CN.md index a83bc9f6..879a8859 100644 --- a/README_CN.md +++ b/README_CN.md @@ -24,7 +24,7 @@ 4. 生成映射关系文档(考虑支持) #### 三、基础功能 -1. 添加依赖 +1. 添加依赖和配置 apply plugin: 'com.neenbedankt.android-apt' @@ -37,9 +37,15 @@ } } + apt { + arguments { + moduleName project.getName(); + } + } + dependencies { - apt 'com.alibaba.android:arouter-compiler:x.x.x' - compile 'com.alibaba.android:arouter-api:x.x.x' + apt 'com.alibaba:arouter-compiler:x.x.x' + compile 'com.alibaba:arouter-api:x.x.x' ... } @@ -283,7 +289,12 @@ 2. 注意:推荐使用ByName方式获取Service,ByType这种方式写起来比较方便,但如果存在多实现的情况时,SDK不保证能获取到你想要的实现 - +10. 使用ARouter管理服务(三) 管理依赖 + + 可以通过ARouter service包装您的业务逻辑或者sdk,在service的init方法中初始化您的sdk,不同的sdk使用ARouter的service进行调用, + 每一个service在第一次使用的时候会被初始化,即调用init方法。 + 这样就可以告别各种乱七八糟的依赖关系的梳理,只要能调用到这个service,那么这个service中所包含的sdk等就已经被初始化过了,完全不需要 + 关心各个sdk的初始化顺序。 #### 五、更多功能 @@ -351,11 +362,5 @@ 3. Jack 编译链的支持 - - 因为不想让用户主动设置一堆乱七八糟的参数,在获取模块名的时候使用javac的api,使用了Jack之后没有了javac,只能让用户稍稍动动手了 - - // 在使用了Jack的模块的build.gradle中加入如下参数即可,moduleName保证和其他模块不重复,使用标准字符,不要使用各种特殊字符 - apt { - arguments { - moduleName 'lalala' - } - } \ No newline at end of file + - ~~因为不想让用户主动设置一堆乱七八糟的参数,在获取模块名的时候使用javac的api,使用了Jack之后没有了javac,只能让用户稍稍动动手了~~ + - 因为一些其他原因,现在任何情况下都需要在build.gradle中配置moduleName了。。。。 \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 00000000..1952ca7a --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,61 @@ +apply plugin: 'com.android.application' +apply plugin: 'com.neenbedankt.android-apt' + +android { + compileSdkVersion Integer.parseInt(COMPILE_SDK_VERSION) + buildToolsVersion BUILDTOOLS_VERSION + + defaultConfig { + minSdkVersion Integer.parseInt(MIN_SDK_VERSION) + targetSdkVersion Integer.parseInt(TARGET_SDK_VERSION) + versionName "0.0.1" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } + + signingConfigs { + debug { + storeFile file("./doc/debug/debug.keystore") + storePassword "android" + keyAlias "androiddebugkey" + keyPassword "android" + } + } + + buildTypes { + debug { + minifyEnabled false + signingConfig signingConfigs.debug + } + + release { + minifyEnabled false + signingConfig null + } + } + + lintOptions { + abortOnError false + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + + apt 'com.alibaba:arouter-compiler:1.0.1' + compile 'com.alibaba:arouter-api:1.0.1' + + compile project(':test-module-1') + compile project(':test-module-2') + + compile 'com.android.support:appcompat-v7:22.2.0' +} + +apt { + arguments { + moduleName project.getName(); + } +} \ No newline at end of file diff --git a/app/doc/debug/debug.keystore b/app/doc/debug/debug.keystore new file mode 100644 index 00000000..34cc5908 Binary files /dev/null and b/app/doc/debug/debug.keystore differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a47e48c4 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/schame-test.html b/app/src/main/assets/schame-test.html new file mode 100644 index 00000000..f49494c0 --- /dev/null +++ b/app/src/main/assets/schame-test.html @@ -0,0 +1,25 @@ + + + + + + + + + +

跳转测试

+ +

自定义Schame[通常来说都是这样的]

+

arouter://m.aliyun.com/test/activity1

+

测试URL Encode情况

+

arouter://m.aliyun.com/test/activity1?name=alex&age=18&boy=true&high=180

+

arouter://m.aliyun.com/test/activity2

+

arouter://m.aliyun.com/test/activity2?key1=value1

+

(需要开启自动注入)arouter://m.aliyun.com/test/activity3?name=alex&age=18&boy=true&high=180

+ +

App Links[防止被App屏蔽]

+

http://m.aliyun.com/test/activity1

+

http://m.aliyun.com/test/activity2

+ + + \ No newline at end of file diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/AppContext.java b/app/src/main/java/com/alibaba/android/arouter/demo/AppContext.java new file mode 100644 index 00000000..ae5f9e33 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/AppContext.java @@ -0,0 +1,44 @@ +package com.alibaba.android.arouter.demo; + +import android.app.Application; +import android.content.Context; + +import com.alibaba.android.arouter.launcher.ARouter; + +/** + * TODO feature + * + * @author Alex Contact me. + * @version 1.0 + * @since 16/8/23 11:54 + */ +public class AppContext extends Application { + + private static Application mInstance; + + @Override + public void onCreate() { + super.onCreate(); + + mInstance = this; + } + + public static Application getInstance() { + return mInstance; + } + + /** + * Set the base context for this ContextWrapper. All calls will then be + * delegated to the base context. Throws + * IllegalStateException if a base context has already been set. + * + * @param base The new base context for this wrapper. + */ + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + +// 实验性功能,不推荐使用 + ARouter.attachBaseContext(); + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java b/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java new file mode 100644 index 00000000..f9c6021d --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/MainActivity.java @@ -0,0 +1,90 @@ +package com.alibaba.android.arouter.demo; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.View; + +import com.alibaba.android.arouter.demo.testservice.HelloService; +import com.alibaba.android.arouter.launcher.ARouter; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + + private static Activity activity; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + activity = this; + } + + public static Activity getThis() { + return activity; + } + + /** + * Called when a view has been clicked. + * + * @param v The view that was clicked. + */ + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.openLog: + ARouter.openLog(); + break; + case R.id.openDebug: + ARouter.openDebug(); + break; + case R.id.init: + ARouter.init(AppContext.getInstance()); + break; + case R.id.normalNavigation: + ARouter.getInstance() + .build("/test/activity2") + .navigation(); + break; + case R.id.normalNavigationWithParams: + ARouter.getInstance() + .build("/test/activity2") + .withString("key1", "value1") + .navigation(); + break; + case R.id.interceptor: + ARouter.getInstance() + .build("/test/activity4") + .navigation(); + break; + case R.id.navByUrl: + ARouter.getInstance() + .build("/test/webview") + .withString("url", "file:///android_asset/schame-test.html") + .navigation(); + break; + case R.id.autoInject: + ARouter.enableAutoInject(); + break; + case R.id.navByName: + ((HelloService)ARouter.getInstance().build("/service/hello").navigation()).sayHello("mike"); + break; + case R.id.navByType: + ARouter.getInstance().navigation(HelloService.class).sayHello("mike"); + break; + case R.id.navToMoudle1: + // 这个页面主动指定了Group名 + ARouter.getInstance().build("/module/1", "m1").navigation(); + break; + case R.id.navToMoudle2: + // 这个页面主动指定了Group名 + ARouter.getInstance().build("/module/2", "m2").navigation(); + break; + case R.id.destroy: + ARouter.getInstance().destroy(); + break; + default: + break; + } + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/MainLooper.java b/app/src/main/java/com/alibaba/android/arouter/demo/MainLooper.java new file mode 100644 index 00000000..fe6eefc4 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/MainLooper.java @@ -0,0 +1,25 @@ +package com.alibaba.android.arouter.demo; + +import android.os.Handler; +import android.os.Looper; + +public class MainLooper extends Handler { + private static MainLooper instance = new MainLooper(Looper.getMainLooper()); + + protected MainLooper(Looper looper) { + super(looper); + } + + public static MainLooper getInstance() { + return instance; + } + + public static void runOnUiThread(Runnable runnable) { + if(Looper.getMainLooper().equals(Looper.myLooper())) { + runnable.run(); + } else { + instance.post(runnable); + } + + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/SchameFilterActivity.java b/app/src/main/java/com/alibaba/android/arouter/demo/SchameFilterActivity.java new file mode 100644 index 00000000..1f5db9f8 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/SchameFilterActivity.java @@ -0,0 +1,31 @@ +package com.alibaba.android.arouter.demo; + +import android.app.Activity; +import android.net.Uri; +import android.os.Bundle; + +import com.alibaba.android.arouter.facade.Postcard; +import com.alibaba.android.arouter.facade.callback.NavigationCallback; +import com.alibaba.android.arouter.launcher.ARouter; + +public class SchameFilterActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + +// 直接通过ARouter处理外部Uri + Uri uri = getIntent().getData(); + ARouter.getInstance().build(uri).navigation(this, new NavigationCallback() { + @Override + public void onFound(Postcard postcard) { + finish(); + } + + @Override + public void onLost(Postcard postcard) { + finish(); + } + }); + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/TestWebview.java b/app/src/main/java/com/alibaba/android/arouter/demo/TestWebview.java new file mode 100644 index 00000000..b9f50a3b --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/TestWebview.java @@ -0,0 +1,23 @@ +package com.alibaba.android.arouter.demo; + +import android.app.Activity; +import android.os.Bundle; +import android.webkit.WebView; + +import com.alibaba.android.arouter.facade.annotation.Route; + +@Route(path = "/test/webview") +public class TestWebview extends Activity { + + WebView webview; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test_webview); + + + webview = (WebView) findViewById(R.id.webview); + webview.loadUrl(getIntent().getStringExtra("url")); + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java new file mode 100644 index 00000000..ef62896b --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test1Activity.java @@ -0,0 +1,47 @@ +package com.alibaba.android.arouter.demo.testactivity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.widget.TextView; + +import com.alibaba.android.arouter.demo.R; +import com.alibaba.android.arouter.facade.annotation.Param; +import com.alibaba.android.arouter.facade.annotation.Route; + +/** + * https://m.aliyun.com/test/activity1?name=老王&age=23&boy=true&high=180 + */ +@Route(path = "/test/activity1") +public class Test1Activity extends AppCompatActivity { + + @Param + private String name; + + @Param + private int age; + + @Param(name = "boy") + private boolean girl; + + private long high; + + @Param + private String url; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test1); + + name = getIntent().getStringExtra("name"); + age = getIntent().getIntExtra("age", 0); + girl = getIntent().getBooleanExtra("girl", false); + high = getIntent().getLongExtra("high", 0); + url = getIntent().getStringExtra("url"); + + String params = String.format("name=%s, age=%s, girl=%s, high=%s, url=%s", name, age, girl, high, url); + + ((TextView)findViewById(R.id.test)).setText("I am " + Test1Activity.class.getName()); + ((TextView)findViewById(R.id.test2)).setText(params); + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test2Activity.java b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test2Activity.java new file mode 100644 index 00000000..23d2927b --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test2Activity.java @@ -0,0 +1,28 @@ +package com.alibaba.android.arouter.demo.testactivity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.widget.Toast; + +import com.alibaba.android.arouter.demo.R; +import com.alibaba.android.arouter.facade.annotation.Param; +import com.alibaba.android.arouter.facade.annotation.Route; + +@Route(path = "/test/activity2") +public class Test2Activity extends AppCompatActivity { + + @Param + private String key1; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test2); + + String value = getIntent().getStringExtra("key1"); + if (!TextUtils.isEmpty(value)) { + Toast.makeText(this, "exist param :" + value, Toast.LENGTH_LONG).show(); + } + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test3Activity.java b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test3Activity.java new file mode 100644 index 00000000..bdeb21bb --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test3Activity.java @@ -0,0 +1,39 @@ +package com.alibaba.android.arouter.demo.testactivity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.widget.TextView; + +import com.alibaba.android.arouter.demo.R; +import com.alibaba.android.arouter.facade.annotation.Param; +import com.alibaba.android.arouter.facade.annotation.Route; + +/** + * 自动注入的测试用例 + */ +@Route(path = "/test/activity3") +public class Test3Activity extends AppCompatActivity { + + @Param + private String name; + + @Param + private int age; + + @Param(name = "boy") + private boolean girl; + + // 这个字段没有注解,是不会自动注入的 + private long high; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test1); + + String params = String.format("name=%s, age=%s, girl=%s, high=%s", name, age, girl, high); + + ((TextView)findViewById(R.id.test)).setText("I am " + Test3Activity.class.getName()); + ((TextView)findViewById(R.id.test2)).setText(params); + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test4Activity.java b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test4Activity.java new file mode 100644 index 00000000..87d5c052 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testactivity/Test4Activity.java @@ -0,0 +1,25 @@ +package com.alibaba.android.arouter.demo.testactivity; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.widget.TextView; + +import com.alibaba.android.arouter.demo.R; +import com.alibaba.android.arouter.facade.annotation.Route; + +@Route(path = "/test/activity4") +public class Test4Activity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test1); + + ((TextView)findViewById(R.id.test)).setText("I am " + Test4Activity.class.getName()); + String extra = getIntent().getStringExtra("extra"); + if (!TextUtils.isEmpty(extra)) { + ((TextView)findViewById(R.id.test2)).setText(extra); + } + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testinterceptor/Test1Interceptor.java b/app/src/main/java/com/alibaba/android/arouter/demo/testinterceptor/Test1Interceptor.java new file mode 100644 index 00000000..7c151463 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testinterceptor/Test1Interceptor.java @@ -0,0 +1,81 @@ +package com.alibaba.android.arouter.demo.testinterceptor; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.util.Log; + +import com.alibaba.android.arouter.demo.MainActivity; +import com.alibaba.android.arouter.demo.MainLooper; +import com.alibaba.android.arouter.demo.testservice.HelloService; +import com.alibaba.android.arouter.facade.Postcard; +import com.alibaba.android.arouter.facade.annotation.Interceptor; +import com.alibaba.android.arouter.facade.callback.InterceptorCallback; +import com.alibaba.android.arouter.facade.template.IInterceptor; + +/** + * TODO feature + * + * @author Alex Contact me. + * @version 1.0 + * @since 2017/1/3 11:20 + */ +@Interceptor(priority = 7) +public class Test1Interceptor implements IInterceptor { + Context mContext; + + /** + * The operation of this interceptor. + * + * @param postcard meta + * @param callback cb + */ + @Override + public void process(final Postcard postcard, final InterceptorCallback callback) { + if ("/test/activity4".equals(postcard.getPath())) { + final AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.getThis()); + ab.setCancelable(false); + ab.setTitle("温馨提醒"); + ab.setMessage("想要跳转到Test4Activity么?(触发了\"/inter/test1\"拦截器,拦截了本次跳转)"); + ab.setNegativeButton("继续", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + callback.onContinue(postcard); + } + }); + ab.setNeutralButton("算了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + callback.onInterrupt(null); + } + }); + ab.setPositiveButton("加点料", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + postcard.withString("extra", "我是在拦截器中附加的参数"); + callback.onContinue(postcard); + } + }); + + MainLooper.runOnUiThread(new Runnable() { + @Override + public void run() { + ab.create().show(); + } + }); + } else { + callback.onContinue(postcard); + } + } + + /** + * Do your init work in this method, it well be call when processor has been load. + * + * @param context ctx + */ + @Override + public void init(Context context) { + mContext = context; + Log.e("testService", HelloService.class.getName() + " has init."); + } +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testservice/HelloService.java b/app/src/main/java/com/alibaba/android/arouter/demo/testservice/HelloService.java new file mode 100644 index 00000000..912e66a4 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testservice/HelloService.java @@ -0,0 +1,14 @@ +package com.alibaba.android.arouter.demo.testservice; + +import com.alibaba.android.arouter.facade.template.IProvider; + +/** + * TODO feature + * + * @author Alex Contact me. + * @version 1.0 + * @since 2017/1/3 10:26 + */ +public interface HelloService extends IProvider { + void sayHello(String name); +} diff --git a/app/src/main/java/com/alibaba/android/arouter/demo/testservice/HelloServiceImpl.java b/app/src/main/java/com/alibaba/android/arouter/demo/testservice/HelloServiceImpl.java new file mode 100644 index 00000000..a6745154 --- /dev/null +++ b/app/src/main/java/com/alibaba/android/arouter/demo/testservice/HelloServiceImpl.java @@ -0,0 +1,35 @@ +package com.alibaba.android.arouter.demo.testservice; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +import com.alibaba.android.arouter.facade.annotation.Route; + +/** + * TODO feature + * + * @author Alex Contact me. + * @version 1.0 + * @since 2017/1/3 10:26 + */ +@Route(path = "/service/hello") +public class HelloServiceImpl implements HelloService { + Context mContext; + + @Override + public void sayHello(String name) { + Toast.makeText(mContext, "Hello " + name, Toast.LENGTH_SHORT).show(); + } + + /** + * Do your init work in this method, it well be call when processor has been load. + * + * @param context ctx + */ + @Override + public void init(Context context) { + mContext = context; + Log.e("testService", HelloService.class.getName() + " has init."); + } +} diff --git a/app/src/main/res/drawable/bg_test_area.xml b/app/src/main/res/drawable/bg_test_area.xml new file mode 100644 index 00000000..4cc2c68c --- /dev/null +++ b/app/src/main/res/drawable/bg_test_area.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..97c295ef --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,187 @@ + + + + + + + + + +