综合示例 Astroboy

1年前 阅读 149 评论 0 赞 0

綜合示例 Astroboy

前面介紹了 RogoGuice2.0 的基本用法,其它使用可以參見 RoboGuice1.1 開發指南,2.0中提供了對 Fragment,View(自定義View 中使用注入)的支持,本博客不再一一介紹。

本例使用的是 RoboGuice 開發包中的簡單示例 Astroboy (阿童木)。涉及的使用 RoboGuice2.0 的一些常用方法。

本例下載(Eclipse項目)

下面對項目中 RoboGuice2 的使用進行解釋。因為本例沒使用自定義綁定,所以無需使用 res/values/roboguice.xml 定義 Module. 如有自定義模塊,可以參見 Android RoboGuice2 使用指南(2): 第一個例子 Hello World

  1. 類 Astroboy
  1. // There's only one Astroboy, so make it a @Singleton.
  2. // This means that there will be only one instance of Astroboy in the entire
  3. // app.
  4. // Any class that requires an instance of Astroboy will get the same instance.
  5. // This also means this class needs to be thread safe, of course
  6. @Singleton
  7. public class Astroboy {
  8. // Because Astroboy is a Singleton, we can't directly inject the current
  9. // Context since the current context may change depending on what activity
  10. // is using Astroboy
  11. // at the time. Instead we use the application context.
  12. // Vibrator is bound to context.getSystemService(VIBRATOR_SERVICE) in
  13. // DefaultRoboModule.
  14. // Random has no special bindings, so Guice will create a new instance for
  15. // us.
  16. @Inject Application application;
  17. @Inject Vibrator vibrator;
  18. @Inject Random random;
  19. public void say(String something) {
  20. // Make a Toast, using the current context as returned by the Context
  21. // Provider
  22. Toast.makeText(application, "Astroboy says, \"" + something + "\"",
  23. Toast.LENGTH_LONG).show();
  24. }
  25. public void brushTeeth() {
  26. vibrator.vibrate(
  27. new long[] { 0, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50,
  28. 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, 200, 50, },
  29. -1);
  30. }
  31. public String punch() {
  32. final String expletives[] = new String[] { "POW!", "BANG!", "KERPOW!",
  33. "OOF!" };
  34. return expletives[random.nextInt(expletives.length)];
  35. }
  36. }

程序中只希望使用一個 Astroboy 實例,因此可以使用 @Singleton 標註,此後任何使用

@Inject Astroboy astroboy;

注入的 Astroboy 都會指向同一個實例,這也是符合 Singleton 設計模式的

@Inject Application application; 注入 Application 實例。參見Android RoboGuice 使用指南(15):Inject Context

@Inject Vibrator vibrator; 注入 Android Vibrator 實例,參見Android RoboGuice 使用指南(16):Standard Injection

@Inject Random random; 對於普通的 Java 類型(POJO),如果該類具有 預設構造函數(不帶參數的等),也可以使用 RoboGuice 自動注入實例。

因此當 Astroboy 創建時,RoboGuice 自動為 application, vibrator, random 創建實例,無需使用 new 或參數傳入來構造它們。

  1. 類 AstroboyRemoteControl
  1. /**
  2. * A class to control Astroboy remotely.
  3. *
  4. * This class uses the current context, so we must make it @ContextSingleton.
  5. * This means that there will be one AstroboyRemoteControl for every activity or
  6. * service that requires one. Note that we actually ask for the Activity, rather
  7. * than the Context (which is the same thing), because we need access to some
  8. * activity-related methods and this saves us from having to downcast to an
  9. * Activity manually.
  10. *
  11. * It also asks RoboGuice to inject the Astroboy instance so we can control him.
  12. *
  13. * What you'll learn in this class - What @ContextScope means and when to use it
  14. * - How to inject an Activity instead of a Context (which is really the same
  15. * thing) - How to use RoboGuice's convenient and flexible logging facility, Ln.
  16. */
  17. @ContextSingleton
  18. public class AstroboyRemoteControl {
  19. // The Astroboy class has been decorated with @Singleton, so this instance
  20. // of Astroboy will be the same instance used elsewhere in our app.
  21. // Injecting an Activity is basically equivalent to "@Inject Context context",
  22. // and thus also requires @ContextScope. If you wanted, you could also
  23. // @Inject Application, Service, etc. wherever appropriate.
  24. @Inject Astroboy astroboy;
  25. @Inject Activity activity;
  26. public void brushTeeth() {
  27. // More info about logging available here:
  28. // http://code.google.com/p/roboguice/wiki/Logging
  29. Ln.d("Sent brushTeeth command to Astroboy");
  30. astroboy.brushTeeth();
  31. }
  32. public void say(String something) {
  33. Ln.d("Sent say(%s) command to Astroboy", something);
  34. astroboy.say(something);
  35. }
  36. public void selfDestruct() {
  37. Toast.makeText(
  38. activity,
  39. "Your evil remote control has exploded! Now Astroboy is FREEEEEEEEEE!",
  40. Toast.LENGTH_LONG).show();
  41. activity.finish();
  42. }
  43. }

與 Singleton 類似的一個 Scope 標註為 @ContextSingleton ,它表示對於每個 Activity 實例有一個實例,不同的 activity 對應不同的實例。

@Inject Astroboy astroboy; 注入同一個 Astroboy 實例(Singleton)。

@Inject Astroboy astroboy; 注入對應的 Activity 實例。

  1. 類 AstroboyMasterConsole
  1. /**
  2. * This activity uses an AstroboyRemoteControl to control Astroboy remotely!
  3. *
  4. * What you'll learn in this class: - How to use @InjectView as a typesafe
  5. * version of findViewById() - How to inject plain old java objects as well
  6. * (POJOs) - When injection happens - Some basics about injection, including
  7. * when injection results in a call to an object's default constructor, versus
  8. * when it does something "special" like call getSystemService()
  9. */
  10. @ContentView(R.layout.main)
  11. public class AstroboyMasterConsole extends RoboActivity {
  12. // Various views that we inject into the activity.
  13. // Equivalent to calling findViewById() in your onCreate(), except more
  14. // succinct
  15. @InjectView(R.id.self_destruct) Button selfDestructButton;
  16. @InjectView(R.id.say_text) EditText sayText;
  17. @InjectView(R.id.brush_teeth) Button brushTeethButton;
  18. @InjectView(tag = "fightevil") Button fightEvilButton; // we can also use tags if we want
  19. // Standard Guice injection of Plain Old Java Objects (POJOs)
  20. // Guice will find or create the appropriate instance of AstroboyRemoteControl for us
  21. // Since we haven't specified a special binding for AstroboyRemoteControl,
  22. // Guice will create a new instance for us using AstroboyRemoteControl's default constructor.
  23. // Contrast this with Vibrator, which is an Android service that is
  24. // pre-bound by RoboGuice.
  25. // Injecting a Vibrator will return a new instance of a Vibrator obtained by
  26. // calling
  27. // context.getSystemService(VIBRATOR_SERVICE). This is configured in
  28. // DefaultRoboModule, which is
  29. // used by default to configure every RoboGuice injector.
  30. @Inject AstroboyRemoteControl remoteControl;
  31. @Inject Vibrator vibrator;
  32. @Override
  33. public void onCreate(Bundle savedInstanceState) {
  34. super.onCreate(savedInstanceState); // @Inject, @InjectResource, and
  35. // @InjectExtra injection happens
  36. // during super.onCreate()
  37. sayText.setOnEditorActionListener(new OnEditorActionListener() {
  38. public boolean onEditorAction(TextView textView, int i,
  39. KeyEvent keyEvent) {
  40. // Have the remoteControl tell Astroboy to say something
  41. remoteControl.say(textView.getText().toString());
  42. textView.setText(null);
  43. return true;
  44. }
  45. });
  46. brushTeethButton.setOnClickListener(new OnClickListener() {
  47. public void onClick(View view) {
  48. remoteControl.brushTeeth();
  49. }
  50. });
  51. selfDestructButton.setOnClickListener(new OnClickListener() {
  52. public void onClick(View view) {
  53. // Self destruct the remoteControl
  54. vibrator.vibrate(2000);
  55. remoteControl.selfDestruct();
  56. }
  57. });
  58. // Fighting the forces of evil deserves its own activity
  59. fightEvilButton.setOnClickListener(new OnClickListener() {
  60. public void onClick(View view) {
  61. startActivity(new Intent(AstroboyMasterConsole.this,
  62. FightForcesOfEvilActivity.class));
  63. }
  64. });
  65. }
  66. }
  67. AstroboyMasterConsole 為主Activity,要使用RoboGuice,則Activity需從RoboActivity派生,其它如ServiceFragment等可以參見Android RoboGuice 使用指南(13):RoboGuice 功能描述。
  68. @InjectView(R.id.self_destruct) Button selfDestructButton; 注入View實例,功能同findViewById 它的另外一種方法是使用Tag,如
  69. @InjectView(tag = fightevil”) Button fightEvilButton ,功能一樣。
  70. 這個類使用@ContentView(R.layout.main) Activity指明ContentView,無需再調用setContentView.
  71. 4. FightForcesOfEvilActivity
  72. /**
  73. * Things you'll learn in this class: - How to inject Resources - How to use
  74. * RoboAsyncTask to do background tasks with injection - What it means to be a @Singleton
  75. */
  76. public class FightForcesOfEvilActivity extends RoboActivity {
  77. @InjectView(R.id.expletive) TextView expletiveText;
  78. // You can also inject resources such as Strings, Drawables, and Animations
  79. @InjectResource(R.anim.expletive_animation) Animation expletiveAnimation;
  80. // AstroboyRemoteControl is annotated as @ContextSingleton, so the instance
  81. // we get in FightForcesOfEvilActivity will be a different instance than
  82. // the one we got in AstroboyMasterConsole
  83. // @Inject AstroboyRemoteControl remoteControl;
  84. @Override
  85. protected void onCreate(Bundle savedInstanceState) {
  86. super.onCreate(savedInstanceState);
  87. setContentView(R.layout.fight_evil);
  88. expletiveText.setAnimation(expletiveAnimation);
  89. expletiveAnimation.start();
  90. // Throw some punches
  91. for (int i = 0; i < 10; ++i)
  92. new AsyncPunch(this) {
  93. @Override
  94. protected void onSuccess(String expletive) throws Exception {
  95. expletiveText.setText(expletive);
  96. }
  97. // We could also override onException() and onFinally() if we
  98. // wanted
  99. }.execute();
  100. }
  101. // This class will call Astroboy.punch() in the background
  102. public static class AsyncPunch extends RoboAsyncTask<String> {
  103. // Because Astroboy is a @Singleton, this will be the same
  104. // instance that we inject elsewhere in our app.
  105. // Random of course will be a new instance of java.util.Random, since
  106. // we haven't specified any special binding instructions anywhere
  107. @Inject Astroboy astroboy;
  108. @Inject Random random;
  109. public AsyncPunch(Context context) {
  110. super(context);
  111. }
  112. public String call() throws Exception {
  113. Thread.sleep(random.nextInt(5 * 1000));
  114. return astroboy.punch();
  115. }
  116. }
  117. }

@InjectResource(R.anim.expletive_animation) Animation expletiveAnimation; 注入資源,可以參見 Android RoboGuice 使用指南(18):Inject Resources

從代碼中可以看出使用 RoboGuice 注入可以簡化程序,運行結果如下圖:

你的支持将鼓励作者继续创作

评论(0)

(无)