观摩Android最高权力的Context通用性接口

前言在Android框架里,俗称”慈禧太后”的至高权力Context接口,这个Context通用性接口,是Android框架里最具有权力地位的接口。例如,只要你能取得这个Context接口,就能调用极具权力象征的startActivity()函数。


ee                                                                        ee

欢迎访问 ==>高老师的博客网页

高焕堂:MISOO(大数据.大思考)联盟.台北中心和东京(日本)分社.总教练


034349424.png034429923.png

EE                                                                        EE

观摩Android最高权力的Context通用性接口


1. 谁来”实现”通用性接口呢?

谁来实现(Implement)通用性接口呢?[ 认识EIT造形 ] 例如下图:

09162845-ae5e18937d014e18b258992a5e58a70

你会回答:当然由<E>来实现这个IE通用性接口。这项答案是对的。由于接口(Interface)就是一个纯粹抽象类(Pure Abstract Class),上图就相当于下图:

09162902-806ac5248cd34f66a103e817306c8cf

一样地,这也是由<E>来实现这个IE类所提供的通用性<operation>接口。   由于IE类里的operation()是抽象函数,<E>必须提供operation()函数的实现代码。然而,有一种状况,就是当我们必须赚写很多个<E>类来实现同一个IE接口时,而且实现代码是相同的;此时将会重复赚写一样的实现代码,其开发和维护成本就上升了。此时,可以采取”委托实现”的架构[�g迎光�R 高�ㄌ� �W�: http://www.cnblogs.com/myEIT/ ]

委托(Delegation)实现

我们可以将上述的IE接口的实现代码集中于一个小类里,如下图里的IE_Impl类:

09162930-ae5b53472f364b779f2524549f69936

此时,<E>的operation()函数可以去调用IE_Impl类里的operation()函数,执行其实现代码了,它(即<E>)的operation()函数就不必重复撰写operation()函数的实现代码了。这项途径,在软件设计上称为”委托”(Delegation)。也可以将IE_Impl类独立出来,如下图所示:

09162941-329a6c08bef54975b90e461d49bbf28

本来是<E>类必须撰写operation()函数的实现代码,为了避免重复撰写实现代码,<E>类就就转而”委托”IE_Impl类,调用它的operation()实现代码。这种架构设计的效益是,<E>类不必再重复撰写operation()函数的实现代码,可节省开发、维护实现代码的负担。当<E>类的个数愈多时,这种架构设计的效益就愈大。如下图所示:

09163005-77bf1b1d389e4d31999ddc40e6e6c62

图里的黑色菱形符号(◆)表示<E>类都会创建一个IE_Impl类的对象,然后<E>类的operation()函数会调用IE_Impl类的operation()的实现代码。也就是,<E>类将它自己的operation()函数的实现工作委托给IE_Impl类去做了。

2. Android的Context通用性接口

在Android框架里,俗称”慈禧太后”的至高权力Context接口,就依循上一小节所叙述的架构,其的详细内涵如下图:

09163025-d8783a21c0fa4b87b3227c490c5b86a

这个Context通用性接口,是Android框架里最具有权力地位的接口。例如,只要你能取得这个Context接口,就能调用极具权力象征的startActivity()函数。

09163123-b2e50e7396cf485ca20ed60b25ea4f6

 从上图可以看到,除了startActivity()函数之外,还有startService()函数、bindService()函数等,都是Android平台上最常用的函数。在Android里,上图的实现代码片段如下:

public class ContextWrapperextends Context {

    Context mBase;

    public ContextWrapper(Context base) {

        mBase = base;

    }

   //………

   @Override public void startActivity(Intent intent) {

          mBase.startActivity(intent);

     }

    @Override public ComponentName startService(Intent service) {

          return mBase.startService(service);

     }

    //………

}

  其中,mBase是指针,用来指向ContextImpl对象的Context接口。也就是说,ContextWrapper对象都会含有一个ContextImpl对象的指针。这让ContextWrapper能透过mBase而调用ContextImpl类里的实现代码。例如,

   public void startActivity(Intent intent) {

          mBase.startActivity(intent);

     }

就是”委托”(Delegation)机制的实际运行了。

class ContextImpl extends Context {

//...........

@Override public void startActivity(Intent intent) {

       warnIfCallingFromSystemProcess();

       startActivity(intent, null);

   }

@Override

public void startActivity(Intent intent, Bundle options) {

        // 实现代码

   }

//………

@Override

public ComponentName startService(Intent service) {

       warnIfCallingFromSystemProcess();

       return startServiceAsUser(service, mUser);

   }

@Override

public ComponentName startServiceAsUser(Intent service, UserHandle user) {

      // 实现代码

   }    

   // ……..

}

3.  举例说明Context通用性接口的应用

在Android框架里,这俗称为”慈禧太后”至高权力的Context接口,其结构,也可以表示如下:

09163348-4170ae8d0aac46a49997c9612f22647

无论是Android手机或是PC等其它设备,皆能透过HTTP来呼叫你手机上的Servlet(如执行于i-Jetty内),然后该Servlet进而呼叫同一支手机内的Android应用程序或服务。

09163438-cae981c1c50a4cbf8db8d807b1ae007

这i-Jetty本身是以Android应用程序形式嵌入(运行)于Android平台里,它可以透过Android框架的API与其它应用程序沟通。因而,在i-Jetty里执行的Servlet程序也能透过该Android API而与其它应用程序沟通、分享数据。例如,在家庭的Android TV里,加入一个i-Jetty插件,来容纳HTML网页和Servlet程序。数千公里外的家庭成员,透过手机Browser解析HTML,与家里的TV沟通,形成大小屏互动、多机整合的架构设计了。

09163513-9f2f7bc506f34c87b7ef755dae29629

 I-Jetty是一支Android应用程序(*.apk),其扮演Container角色,让许多支Servlet程序可以在Android手机里执行。然而,这些Servlet程序经常需要与同一只手机里的其它Android应用程序沟通,例如启动晨钟或闹铃等等。此时,只要能取得Android框架的Context接口,就能呼叫Android的服务了。这个Context界面位居幕后,仅从应用程序代码的表面,常常看不到,然而它却是Android平台框架的最主要服务窗口。Context接口提供数十个大家很常用的服务,例如startService()、sendBroadcast()函数等。

   由于Activity也是继承Context抽象父类别,意味着Activity也是实作(Implements)这个Context界面。所以我们在Android应用程序里(如myActivity子类别)随时可呼叫Context接口里的函数,如下述的程序范例:

// Android程序范例

//.........

public class ac01 extends Activity implements OnClickListener {

      private Button btn, btn3;

      @Override protected void onCreate(Bundle icicle) {

            super.onCreate(icicle);

            //…….

            setContentView(layout);

       }

     public void onClick(View v) {

           if(v == btn)  

                  startService(new Intent(this, myService.class));

           else if(v == btn3)    

                  finish();

 }}

其中的指令: startService(new Intent(this, myService.class));

相当于指令: this.startService(new Intent(this, myService.class));

意味着,其呼叫到Context接口的startService()函数。其幕后机制是,myActivity类别呼叫到ContextWrapper类别的Context接口(的startService()函数),然后转而呼叫其mBase的(例如ApplicationContext的对象)Context接口的startService()函数。除了startService()函数之外,Context接口还含有许多其它函数,例如getApplicationContext()函数等。


手机内的I-Jetty与Android沟通

同理,我们撰写i-Jetty里的myServlet程序时,也能透过Context接口来呼叫startService()函数来启动Android应用程序里的myService子类别,也能呼叫Context接口startActivity()函数来启动Android应用程序里的myActivity子类别,如下图:

09163751-2368f1168ae04d5b8a4b3582f2d5ad0

(Context接口扮演Android云端整合的重要接口)

 在myServlet子类别里可利用指令:

                 config.getServletContext().getAttribute("org.mortbay.ijetty.context");

指令来取得其当下的Context接口,如下述i-Jetty的范例程序代码:

/* --- i-Jetty的Servlet程序范例 ----*/

/**** 摘自i-Jetty套件的范例 ****/

import java.io.IOException;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class HelloWorld extends HttpServlet {

    String proofOfLife = null;

    public void init(ServletConfig config) throws ServletException {

            super.init(config);

            Object o =

                 config.getServletContext().getAttribute("org.mortbay.ijetty.contentResolver");

            android.content.ContentResolver resolver

                 = (android.content.ContentResolver)o;

android.content.Context androidContext

                = (android.content.Context) config.getServletContext().getAttribute("org.mortbay.ijetty.context");

            proofOfLife = androidContext.getApplicationInfo().packageName;

 }

 public void doPost(HttpServletRequest request, HttpServletResponse response)

                         throws ServletException, IOException

       {  doGet(request, response);   }

public void doGet(HttpServletRequest request, HttpServletResponse response)

                        throws ServletException, IOException {

       response.setContentType("text/html");

       ServletOutputStream out = response.getOutputStream();

       out.println("<html>");

       out.println("<h1>Hello From Servlet Land!</h1>");

       out.println("Brought to you by: "+proofOfLife);

       out.println("</html>");

       out.flush();

   }

}

I-Jetty与Android的跨手机沟通

 上图里是从同一支手机(本机)里的myActivity来呼叫本机的Servlet接口,这是可行的,但是意义比较小。更大的意义是:由别的手机里的myActivity来传送HTTP呼叫到本机的Servlet接口,呼叫到本机的myServlet子类别;然后由myServlet呼叫Android的Context接口,而完成两支手机里两个myActivity子类别之间的相互沟通。如下图:

09164049-135bebfdaff34e7a82720fbb8dfb543

(两支手机之通讯)

于是,Context和Servlet两大接口,成为Android**云的喜鹊桥的两个主要桥墩。

DDD&& �⒖嘉恼�(请点选) &&DDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDD

1. 智能家庭的软硬整合<A段架构设计>_案例解说

2. <家庭物联网><移动互联网>衔接的案例&实践代码

3. 智能&大数据时代,架构师思维的十个步骤和演练

4. <基于框架(Framework)的平台开发技>百篇文章

5. 高焕堂的9eBooks(可下载)

DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD


你可能感兴趣的:(android,软硬整合,高�ㄌ�)