Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划 (四)

 这个Server继承了Android系统应用程序框架层提供的Service类,当它被启动时,运行在一个独立的进程中。当这个Server被启动时,它的onCreate函数就会被调用,然后它就通过ServiceManager的addService接口来添加MemoryService了:

 

 

[java] view plain copy print ?
  1. memoryService = new MemoryService();  
  2.   
  3. try {  
  4.     ServiceManager.addService("AnonymousSharedMemory", memoryService);  
  5.     Log.i(LOG_TAG, "Succeed to add memory service.");  
  6. catch (RuntimeException ex) {  
  7.     Log.i(LOG_TAG, "Failed to add Memory Service.");  
  8.     ex.printStackTrace();  
  9. }  
[java] view plain copy print ?
  1. memoryService = new MemoryService();  
  2.   
  3. try {  
  4.     ServiceManager.addService("AnonymousSharedMemory", memoryService);  
  5.     Log.i(LOG_TAG, "Succeed to add memory service.");  
  6. catch (RuntimeException ex) {  
  7.     Log.i(LOG_TAG, "Failed to add Memory Service.");  
  8.     ex.printStackTrace();  
  9. }  
    memoryService = new MemoryService();

    try {
        ServiceManager.addService("AnonymousSharedMemory", memoryService);
        Log.i(LOG_TAG, "Succeed to add memory service.");
    } catch (RuntimeException ex) {
        Log.i(LOG_TAG, "Failed to add Memory Service.");
        ex.printStackTrace();
    }

       这样,当这个Server成功启动了,Client就可以通过ServiceManager的getService接口来获取这个MemoryService了。

 

       接着,我们就来看Client端的实现。Client端是一个Activity,实现在src/shy/luo/ashmem/Client.java文件中:

 

[java] view plain copy print ?
  1. package shy.luo.ashmem;  
  2.   
  3. import java.io.FileDescriptor;  
  4. import java.io.IOException;  
  5.   
  6. import shy.luo.ashmem.R;  
  7. import android.app.Activity;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.os.MemoryFile;  
  11. import android.os.ParcelFileDescriptor;  
  12. import android.os.ServiceManager;  
  13. import android.os.RemoteException;  
  14. import android.util.Log;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.widget.Button;  
  18. import android.widget.EditText;  
  19.   
  20. public class Client extends Activity implements OnClickListener {  
  21.     private final static String LOG_TAG = "shy.luo.ashmem.Client";  
  22.       
  23.     IMemoryService memoryService = null;  
  24.     MemoryFile memoryFile = null;  
  25.       
  26.     private EditText valueText = null;  
  27.     private Button readButton = null;  
  28.     private Button writeButton = null;  
  29.     private Button clearButton = null;  
  30.       
  31.         @Override  
  32.         public void onCreate(Bundle savedInstanceState) {  
  33.             super.onCreate(savedInstanceState);  
  34.             setContentView(R.layout.main);  
  35.   
  36.         IMemoryService ms = getMemoryService();  
  37.         if(ms == null) {          
  38.                 startService(new Intent("shy.luo.ashmem.server"));  
  39.         } else {  
  40.             Log.i(LOG_TAG, "Memory Service has started.");  
  41.         }  
  42.   
  43.             valueText = (EditText)findViewById(R.id.edit_value);  
  44.             readButton = (Button)findViewById(R.id.button_read);  
  45.             writeButton = (Button)findViewById(R.id.button_write);  
  46.             clearButton = (Button)findViewById(R.id.button_clear);  
  47.   
  48.         readButton.setOnClickListener(this);  
  49.             writeButton.setOnClickListener(this);  
  50.             clearButton.setOnClickListener(this);  
  51.           
  52.             Log.i(LOG_TAG, "Client Activity Created.");  
  53.         }  
  54.   
  55.         @Override  
  56.         public void onResume() {  
  57.         super.onResume();  
  58.   
  59.         Log.i(LOG_TAG, "Client Activity Resumed.");  
  60.         }  
  61.   
  62.         @Override  
  63.         public void onPause() {  
  64.         super.onPause();  
  65.   
  66.         Log.i(LOG_TAG, "Client Activity Paused.");  
  67.         }  
  68.       
  69.         @Override  
  70.         public void onClick(View v) {  
  71.             if(v.equals(readButton)) {  
  72.                 int val = 0;  
  73.               
  74.                 MemoryFile mf = getMemoryFile();  
  75.                 if(mf != null) {  
  76.                 try {  
  77.                         byte[] buffer = new byte[4];  
  78.                         mf.readBytes(buffer, 004);  
  79.                   
  80.                         val = (buffer[0] << 24) | ((buffer[1] & 0xFF) << 16) | ((buffer[2] & 0xFF) << 8) | (buffer[3] & 0xFF);  
  81.                 } catch(IOException ex) {  
  82.                     Log.i(LOG_TAG, "Failed to read bytes from memory file.");  
  83.                     ex.printStackTrace();  
  84.                 }  
  85.                 }     
  86.               
  87.                 String text = String.valueOf(val);  
  88.                 valueText.setText(text);  
  89.             } else if(v.equals(writeButton)) {  
  90.                 String text = valueText.getText().toString();  
  91.                 int val = Integer.parseInt(text);  
  92.               
  93.                 IMemoryService ms = getMemoryService();  
  94.                 if(ms != null) {  
  95.                 try {  
  96.                         ms.setValue(val);  
  97.                 } catch(RemoteException ex) {  
  98.                     Log.i(LOG_TAG, "Failed to set value to memory service.");  
  99.                     ex.printStackTrace();  
  100.                 }  
  101.                 }  
  102.             } else if(v.equals(clearButton)) {  
  103.                 String text = "";  
  104.                 valueText.setText(text);  
  105.             }  
  106.         }  
  107.       
  108.         private IMemoryService getMemoryService() {  
  109.             if(memoryService != null) {  
  110.                 return memoryService;  
  111.             }  
  112.           
  113.             memoryService = IMemoryService.Stub.asInterface(  
  114.                             ServiceManager.getService("AnonymousSharedMemory"));  
  115.   
  116.         Log.i(LOG_TAG, memoryService != null ? "Succeed to get memeory service." : "Failed to get memory service.");  
  117.           
  118.             return memoryService;  
  119.         }  
  120.       
  121.         private MemoryFile getMemoryFile() {  
  122.             if(memoryFile != null) {  
  123.                 return memoryFile;  
  124.             }  
  125.               
  126.             IMemoryService ms = getMemoryService();  
  127.             if(ms != null) {  
  128.             try {  
  129.                     ParcelFileDescriptor pfd = ms.getFileDescriptor();  
  130.                 if(pfd == null) {  
  131.                     Log.i(LOG_TAG, "Failed to get memory file descriptor.");  
  132.                     return null;  
  133.                 }  
  134.   
  135.                 try {  
  136.                     FileDescriptor fd = pfd.getFileDescriptor();  
  137.                     if(fd == null) {  
  138.                         Log.i(LOG_TAG, "Failed to get memeory file descriptor.");  
  139.                         return null;                        
  140.                     }     
  141.   
  142.                         memoryFile = new MemoryFile(fd, 4"r");  
  143.                 } catch(IOException ex) {  
  144.                     Log.i(LOG_TAG, "Failed to create memory file.");  
  145.                     ex.printStackTrace();  
  146.                 }  
  147.                 } catch(RemoteException ex) {  
  148.                 Log.i(LOG_TAG, "Failed to get file descriptor from memory service.");  
  149.                 ex.printStackTrace();  
  150.             }  
  151.         }  
  152.           
  153.             return memoryFile;  
  154.         }  
  155. }  
[java] view plain copy print ?
  1. package shy.luo.ashmem;  
  2.   
  3. import java.io.FileDescriptor;  
  4. import java.io.IOException;  
  5.   
  6. import shy.luo.ashmem.R;  
  7. import android.app.Activity;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.os.MemoryFile;  
  11. import android.os.ParcelFileDescriptor;  
  12. import android.os.ServiceManager;  
  13. import android.os.RemoteException;  
  14. import android.util.Log;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.widget.Button;  
  18. import android.widget.EditText;  
  19.   
  20. public class Client extends Activity implements OnClickListener {  
  21.     private final static String LOG_TAG = "shy.luo.ashmem.Client";  
  22.       
  23.     IMemoryService memoryService = null;  
  24.     MemoryFile memoryFile = null;  
  25.       
  26.     private EditText valueText = null;  
  27.     private Button readButton = null;  
  28.     private Button writeButton = null;  
  29.     private Button clearButton = null;  
  30.       
  31.         @Override  
  32.         public void onCreate(Bundle savedInstanceState) {  
  33.             super.onCreate(savedInstanceState);  
  34.             setContentView(R.layout.main);  
  35.   
  36.         IMemoryService ms = getMemoryService();  
  37.         if(ms == null) {          
  38.                 startService(new Intent("shy.luo.ashmem.server"));  
  39.         } else {  
  40.             Log.i(LOG_TAG, "Memory Service has started.");  
  41.         }  
  42.   
  43.             valueText = (EditText)findViewById(R.id.edit_value);  
  44.             readButton = (Button)findViewById(R.id.button_read);  
  45.             writeButton = (Button)findViewById(R.id.button_write);  
  46.             clearButton = (Button)findViewById(R.id.button_clear);  
  47.   
  48.         readButton.setOnClickListener(this);  
  49.             writeButton.setOnClickListener(this);  
  50.             clearButton.setOnClickListener(this);  
  51.           
  52.             Log.i(LOG_TAG, "Client Activity Created.");  
  53.         }  
  54.   
  55.         @Override  
  56.         public void onResume() {  
  57.         super.onResume();  
  58.   
  59.         Log.i(LOG_TAG, "Client Activity Resumed.");  
  60.         }  
  61.   
  62.         @Override  
  63.         public void onPause() {  
  64.         super.onPause();  
  65.   
  66.         Log.i(LOG_TAG, "Client Activity Paused.");  
  67.         }  
  68.       
  69.         @Override  
  70.         public void onClick(View v) {  
  71.             if(v.equals(readButton)) {  
  72.                 int val = 0;  
  73.               
  74.                 MemoryFile mf = getMemoryFile();  
  75.                 if(mf != null) {  
  76.                 try {  
  77.                         byte[] buffer = new byte[4];  
  78.                         mf.readBytes(buffer, 004);  
  79.                   
  80.                         val = (buffer[0] << 24) | ((buffer[1] & 0xFF) << 16) | ((buffer[2] & 0xFF) << 8) | (buffer[3] & 0xFF);  
  81.                 } catch(IOException ex) {  
  82.                     Log.i(LOG_TAG, "Failed to read bytes from memory file.");  
  83.                     ex.printStackTrace();  
  84.                 }  
  85.                 }     
  86.               
  87.                 String text = String.valueOf(val);  
  88.                 valueText.setText(text);  
  89.             } else if(v.equals(writeButton)) {  
  90.                 String text = valueText.getText().toString();  
  91.                 int val = Integer.parseInt(text);  
  92.               
  93.                 IMemoryService ms = getMemoryService();  
  94.                 if(ms != null) {  
  95.                 try {  
  96.                         ms.setValue(val);  
  97.                 } catch(RemoteException ex) {  
  98.                     Log.i(LOG_TAG, "Failed to set value to memory service.");  
  99.                     ex.printStackTrace();  
  100.                 }  
  101.                 }  
  102.             } else if(v.equals(clearButton)) {  
  103.                 String text = "";  
  104.                 valueText.setText(text);  
  105.             }  
  106.         }  
  107.       
  108.         private IMemoryService getMemoryService() {  
  109.             if(memoryService != null) {  
  110.                 return memoryService;  
  111.             }  
  112.           
  113.             memoryService = IMemoryService.Stub.asInterface(  
  114.                             ServiceManager.getService("AnonymousSharedMemory"));  
  115.   
  116.         Log.i(LOG_TAG, memoryService != null ? "Succeed to get memeory service." : "Failed to get memory service.");  
  117.           
  118.             return memoryService;  
  119.         }  
  120.       
  121.         private MemoryFile getMemoryFile() {  
  122.             if(memoryFile != null) {  
  123.                 return memoryFile;  
  124.             }  
  125.               
  126.             IMemoryService ms = getMemoryService();  
  127.             if(ms != null) {  
  128.             try {  
  129.                     ParcelFileDescriptor pfd = ms.getFileDescriptor();  
  130.                 if(pfd == null) {  
  131.                     Log.i(LOG_TAG, "Failed to get memory file descriptor.");  
  132.                     return null;  
  133.                 }  
  134.   
  135.                 try {  
  136.                     FileDescriptor fd = pfd.getFileDescriptor();  
  137.                     if(fd == null) {  
  138.                         Log.i(LOG_TAG, "Failed to get memeory file descriptor.");  
  139.                         return null;                        
  140.                     }     
  141.   
  142.                         memoryFile = new MemoryFile(fd, 4"r");  
  143.                 } catch(IOException ex) {  
  144.                     Log.i(LOG_TAG, "Failed to create memory file.");  
  145.                     ex.printStackTrace();  
  146.                 }  
  147.                 } catch(RemoteException ex) {  
  148.                 Log.i(LOG_TAG, "Failed to get file descriptor from memory service.");  
  149.                 ex.printStackTrace();  
  150.             }  
  151.         }  
  152.           
  153.             return memoryFile;  
  154.         }  
  155. }  
package shy.luo.ashmem;

import java.io.FileDescriptor;
import java.io.IOException;

import shy.luo.ashmem.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class Client extends Activity implements OnClickListener {
	private final static String LOG_TAG = "shy.luo.ashmem.Client";
	
	IMemoryService memoryService = null;
	MemoryFile memoryFile = null;
	
	private EditText valueText = null;
	private Button readButton = null;
	private Button writeButton = null;
	private Button clearButton = null;
	
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
        	super.onCreate(savedInstanceState);
        	setContentView(R.layout.main);

		IMemoryService ms = getMemoryService();
		if(ms == null) {        
        		startService(new Intent("shy.luo.ashmem.server"));
		} else {
			Log.i(LOG_TAG, "Memory Service has started.");
		}

        	valueText = (EditText)findViewById(R.id.edit_value);
        	readButton = (Button)findViewById(R.id.button_read);
        	writeButton = (Button)findViewById(R.id.button_write);
        	clearButton = (Button)findViewById(R.id.button_clear);

		readButton.setOnClickListener(this);
        	writeButton.setOnClickListener(this);
        	clearButton.setOnClickListener(this);
        
        	Log.i(LOG_TAG, "Client Activity Created.");
    	}

    	@Override
    	public void onResume() {
		super.onResume();

		Log.i(LOG_TAG, "Client Activity Resumed.");
    	}

    	@Override
    	public void onPause() {
		super.onPause();

		Log.i(LOG_TAG, "Client Activity Paused.");
    	}
    
    	@Override
    	public void onClick(View v) {
    		if(v.equals(readButton)) {
    			int val = 0;
    		
    			MemoryFile mf = getMemoryFile();
    			if(mf != null) {
				try {
    					byte[] buffer = new byte[4];
    					mf.readBytes(buffer, 0, 0, 4);
    			
    					val = (buffer[0] << 24) | ((buffer[1] & 0xFF) << 16) | ((buffer[2] & 0xFF) << 8) | (buffer[3] & 0xFF);
				} catch(IOException ex) {
					Log.i(LOG_TAG, "Failed to read bytes from memory file.");
					ex.printStackTrace();
				}
    			}	
    		
    			String text = String.valueOf(val);
    			valueText.setText(text);
    		} else if(v.equals(writeButton)) {
    			String text = valueText.getText().toString();
    			int val = Integer.parseInt(text);
    		
    			IMemoryService ms = getMemoryService();
    			if(ms != null) {
				try {
    					ms.setValue(val);
				} catch(RemoteException ex) {
					Log.i(LOG_TAG, "Failed to set value to memory service.");
					ex.printStackTrace();
				}
    			}
    		} else if(v.equals(clearButton)) {
    			String text = "";
    			valueText.setText(text);
    		}
    	}
    
    	private IMemoryService getMemoryService() {
    		if(memoryService != null) {
    			return memoryService;
    		}
    	
    		memoryService = IMemoryService.Stub.asInterface(
                			ServiceManager.getService("AnonymousSharedMemory"));

		Log.i(LOG_TAG, memoryService != null ? "Succeed to get memeory service." : "Failed to get memory service.");
    	
    		return memoryService;
    	}
    
    	private MemoryFile getMemoryFile() {
    		if(memoryFile != null) {
    			return memoryFile;
    		}
    		
    		IMemoryService ms = getMemoryService();
    		if(ms != null) {
			try {
    				ParcelFileDescriptor pfd = ms.getFileDescriptor();
				if(pfd == null) {
					Log.i(LOG_TAG, "Failed to get memory file descriptor.");
					return null;
				}

				try {
					FileDescriptor fd = pfd.getFileDescriptor();
					if(fd == null) {
						Log.i(LOG_TAG, "Failed to get memeory file descriptor.");
						return null;                      
					}	

    					memoryFile = new MemoryFile(fd, 4, "r");
				} catch(IOException ex) {
					Log.i(LOG_TAG, "Failed to create memory file.");
					ex.printStackTrace();
				}
    			} catch(RemoteException ex) {
				Log.i(LOG_TAG, "Failed to get file descriptor from memory service.");
				ex.printStackTrace();
			}
		}
    	
    		return memoryFile;
    	}
}

        Client端的界面主要包含了三个按钮Read、Write和Clear,以及一个用于显示内容的文本框。

 

        这个Activity在onCreate时,会通过startService接口来启动我们前面定义的Server进程。调用startService时,需要指定要启动的服务的名称,这里就是"shy.luo.ashmem.server"了,后面我们会在程序的描述文件AndroidManifest.xml看到前面的Server类是如何和名称"shy.luo.ashmem.server"关联起来的。关于调用startService函数来启动自定义服务的过程,可以参考Android系统在新进程中启动自定义服务过程(startService)的原理分析一文。

        内部函数getMemoryService用来获取IMemoryService。如果是第一次调用该函数,则会通过ServiceManager的getService接口来获得这个IMemoryService接口,然后保存在类成员变量memoryService中,以后再调用这个函数时,就可以直接返回memoryService了。

        内部函数getMemoryFile用来从MemoryService中获得匿名共享内存文件的描述符。同样,如果是第一次调用该函数,则会通过IMemoryService的getFileDescriptor接口来获得MemoryService中的匿名共享内存文件的描述符,然后用这个文件描述符来创建一个MemoryFile实例,并保存在类成员变量memoryFile中,以后再调用这个函数时,就可以直接返回memoryFile了。

        有了memoryService和memoryFile后,我们就可以在Client端访问Server端创建的匿名共享内存了。点击Read按钮时,就通过memoryFile的readBytes接口把共享内存中的整数读出来,并显示在文本框中;点击Write按钮时,就通过memoryService这个代理类的setVal接口来调用MemoryService的本地实现类的setVal服务,从而把文本框中的数值写到Server端创建的匿名共享内存中去;点击Clear按钮时,就会清空文本框的内容。这样,我们就可以通过Read和Write按钮来验证我们是否在Client和Server两个进程中实现内存共享了。

       现在,我们再来看看Client界面的配置文件,它定义在res/layout/main.xml文件中:

 

[html] view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7.     <LinearLayout  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:orientation="vertical"   
  11.         android:gravity="center">  
  12.         <TextView   
  13.             android:layout_width="wrap_content"  
  14.             android:layout_height="wrap_content"   
  15.             android:text="@string/value">  
  16.         </TextView>  
  17.         <EditText   
  18.             android:layout_width="fill_parent"  
  19.             android:layout_height="wrap_content"   
  20.             android:id="@+id/edit_value"  
  21.             android:hint="@string/hint">  
  22.         </EditText>  
  23.     </LinearLayout>  
  24.      <LinearLayout  
  25.         android:layout_width="fill_parent"  
  26.         android:layout_height="wrap_content"  
  27.         android:orientation="horizontal"   
  28.         android:gravity="center">  
  29.         <Button   
  30.             android:id="@+id/button_read"  
  31.             android:layout_width="wrap_content"  
  32.             android:layout_height="wrap_content"  
  33.             android:text="@string/read">  
  34.         </Button>  
  35.         <Button   
  36.             android:id="@+id/button_write"  
  37.             android:layout_width="wrap_content"  
  38.             android:layout_height="wrap_content"  
  39.             android:text="@string/write">  
  40.         </Button>  
  41.         <Button   
  42.             android:id="@+id/button_clear"  
  43.             android:layout_width="wrap_content"  
  44.             android:layout_height="wrap_content"  
  45.             android:text="@string/clear">  
  46.         </Button>  
  47.     </LinearLayout>  
  48. </LinearLayout>  

你可能感兴趣的:(移动开发)