当前位置:  编程技术>移动开发
本页文章导读:
    ▪应用apns构建push服务开发思路        使用apns构建push服务开发思路       上一次折腾PUSH服务已经好几个月了,终于抽空重构了(APNS:Apple Push Notification Service,我谈的其实只是构建一个中间平台去调用apns服务)。         .........
    ▪ 施用contentprovider共享生词本数据        使用contentprovider共享生词本数据 摘自李刚<疯狂android>备份学习使用首先我们为该contentprovider定义一个工具类,该类中只是包含一个public static的常量,该工具类的代码如下: import android.ne.........
    ▪ 两个double数组互相赋值       两个double数组相互赋值 两个double数组相互赋值:double [][] a = new double[10][10];double [][] b = new double[10][10];a = b;//a 和 b 是指向a数组和b数组的地址的指针,此操作是把指向a数组的指针指向了b数.........

[1]应用apns构建push服务开发思路
    来源: 互联网  发布时间: 2014-02-18
使用apns构建push服务开发思路

      上一次折腾PUSH服务已经好几个月了,终于抽空重构了(APNS:Apple Push Notification Service,我谈的其实只是构建一个中间平台去调用apns服务)。       

      先介绍下之前所做的push服务的设计模型

 

当初的设计比较简单,将压力全部放在了推送消息处理线程上,线程不仅需要建立apns服务器的通信,也需要对广播消息进行转换。对于单播消息而言性能似乎还可以接受,然而对广播消息处理,线程的处理性能明显降低。因为apns服务是不支持广播消息的,进行广播必须要获取到所有广播对象的devicetoken,这就需要线程去批量获取推送对象列表,并将这个列表组成单播message,而后批量发送。这样的设计将消息处理和发送耦合在了一起,无法并行处理。虽然通过异步通信的方式实现了批量发送,但是总体而言性能还是很低的。

       之前设计最根本的的问题是耦合了广播消息本身的处理和发送的处理,发挥不了多线程处理的性能。这次重构,主要的性能优化就是,区分了推送请求队列和推送消息队列,请求处理线程只专注对推送请求的处理,生成可用于直接发送的推送报文,并均衡负载到推送消息队列上。推送线程则专注于推送本身,每个线程hold一个与apns的连接,发送推送报文。

将push请求处理和push发送处理分开,也给系统扩展提供了更多的可能性。单服务器可以设置多个请求队列、多个发送队列,每个队列允许多个线程进行监听处理。也可以将推送请求处理和发送处理分开部署,并进行均衡负载。

       废话了这么多,最后再戳下漏洞:由于没有区分消息级别,即时消息可能会淹没在队列中。对于实时性要求不是非常高的一般应用上面的模型还能凑合使用。大家有什么好的设计思路欢迎讨论。

 

欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

 


    
[2] 施用contentprovider共享生词本数据
    来源: 互联网  发布时间: 2014-02-18
使用contentprovider共享生词本数据
摘自李刚<疯狂android>备份学习使用

首先我们为该contentprovider定义一个工具类,该类中只是包含一个public static的常量,该工具类的代码如下:
import android.net.Uri;
import android.provider.BaseColumns;

public final class Words {
	
	//定义该contentprovider的authority
	public static final String AUTHORITY = "org.crazyit.providers.dictprovider";
	
	//定义一个静态内部类
	public static final class Word implements BaseColumns{
		
		//定义content所允许操作的三个数据列
		public static final String _ID = "_id";
		public static final String WORD = "word";
		public static final String DETAIL = "detail";
		
		//定义该content提供服务的两个Uri
		public static final Uri DICT_CONTETN_URI =
			Uri.parse("content://" + AUTHORITY + "/words");
		public static final Uri WORD_CONTENT_URI = 
			Uri.parse("content://" + AUTHORITY + "/word");
	}
}


上面的工具类只是定义了一些简单的工具类,这个工具类的作用就是告诉其他应用程序,访问该contentprovider的一些常用入口。

数据库创建MyDatabaseHelper代码:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDatabaseHelper extends SQLiteOpenHelper{

	private final String CREATE_TABLE_SQL= 
		"create table dict(_id integer primary key autoincrement, word , detail)";
	
	public MyDatabaseHelper(Context context, String name,
			CursorFactory factory, int version) {
		super(context, name, factory, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(CREATE_TABLE_SQL);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		System.out.println("--------onUpdate Called--------"
				+ oldVersion + "----->" + newVersion);
	}

}



接下来我们开发一个contentprovider的子类,并重写其中的增、删、改、查等方法,类代码如下。

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

import com.dictprovider.content.Words;
import com.mydatabasehelper.database.MyDatabaseHelper;

public class DictProvider extends ContentProvider{

	private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
	private static final int WORDS = 1;
	private static final int WORD = 2;
	private MyDatabaseHelper dbOpenHelper;
	
	static{
		matcher.addURI(Words.AUTHORITY, "words", WORDS);
		matcher.addURI(Words.AUTHORITY, "word/#", WORD);
	}
	
	//第一次调用该DictProvider时,系统先创建DictProvider对象,并回调该方法
	@Override
	public boolean onCreate() {
		dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", null, 1);
		return true;
	}
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		//获得数据库实例
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		long rowId = db.insert("dict", Words.Word._ID, values);
		//如果插入成功则返回uri
		if(rowId > 0){
			//在已有的Uri的后面追加ID数据
			Uri wordUri = ContentUris.withAppendedId(uri, rowId);
			//通知数据已经改变
			getContext().getContentResolver().notifyChange(wordUri, null);
			return wordUri;
		}
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		//记录所删除的记录数
		int num = 0;
		//对uri进行匹配
		switch(matcher.match(uri)){
		case WORDS:{
			num = db.delete("dict", selection, selectionArgs);
			break;
		}
		case WORD:{
			long id = ContentUris.parseId(uri);
			String where = Words.Word._ID + "=" + id;
			//如果原来的where子句存在,拼接where子句
			if(selection != null && !selection.equals("")){
				where = where + " and " + selection;
			}
			num = db.delete("dict", where, selectionArgs);
			break;
		}
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return num;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		int num = 0;
		switch(matcher.match(uri)){
		case WORDS:{
			num = db.update("dict", values, selection, selectionArgs);
			break;
		}
		case WORD:{
			long id = ContentUris.parseId(uri);
			String where = Words.Word._ID + "=" + id;
			if(selection != null && !"".equals(selection)){
				where = where + " and " + selection;
			}
			num = db.update("dict", values, where, selectionArgs);
			break;
		}
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return num;
	}

	
	@Override
	public String getType(Uri uri) {
		switch(matcher.match(uri)){
		case WORDS:{
			return "vnd.android.cursor.dir/org.crazyit.dict";
		}
		case WORD:{
			return "vnd.android.cursor.item/org.crazyit.dict";
		}
		}
		return null;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		switch(matcher.match(uri)){
		case WORDS:{
			return db.query("dict", projection, selection, selectionArgs, null, null, sortOrder);
		}
		case WORD:{
			long id = ContentUris.parseId(uri);
			String where = Words.Word._ID + "=" + id;
			if(selection != null && !selection.equals("")){
				where = where + " and " + selection;
			}
			return db.query("dict", projection, selection, selectionArgs, null, null, sortOrder);
		}
		}
		return null;
	}
}



上面的dictProvider类很简单,它除了继承系统的contentprovider之外,还实现了操作数据的增、删、改、查等方法,那木该contentprovider就开发完成了。

接下来需要在androidmanifest.xml文件中注册该contentprovider,这就需要在androidmanifest.xml文件中增加如下配置片段:
<provider android:name="com.dictprovider.provider.DictProvider"
            android:authorities="org.crazyit.providers.dictprovider"/>


至此,暴露生词本数据的contentprovider开发完成。为了测试该contentprovider的开发是否成功,接下来再开发一个应用程序,该应用程序将会通过contentresolver来操作生词本中的数据。
该程序同样提供了添加生词、查询生词的功能,只是改程序并不保存数据,而是访问前面dictProvider所共享的数据,下面是contentresolver的类的代码。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.dictprovider.content.Words;
import com.dictprovider.observer.WordObserver;

public class MainActivity extends Activity {

	ContentResolver contentResolver;
	Button insert = null;
	Button search = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//获取系统contentresolver对象
		contentResolver = getContentResolver();
		getContentResolver().registerContentObserver(Uri.parse("content://" + Words.AUTHORITY), true, new WordObserver(this,new Handler()));
		
		
		insert = (Button)findViewById(R.id.insert);
		search = (Button)findViewById(R.id.search);
		
		insert.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				String word = ((EditText)findViewById(R.id.word)).getText().toString();
				String detail = ((EditText)findViewById(R.id.detail)).getText().toString();
				
				//插入生词记录
				ContentValues values = new ContentValues();
				values.put(Words.Word.WORD, word);
				values.put(Words.Word.DETAIL, detail);
				contentResolver.insert(Words.Word.DICT_CONTETN_URI, values);
				Toast.makeText(MainActivity.this, "insert success", Toast.LENGTH_SHORT).show();
			}
		});
		
		search.setOnClickListener(new OnClickListener() {
			
			//获取用户输入
			@Override
			public void onClick(View v) {
				String key = ((EditText)findViewById(R.id.key)).getText().toString();
			
			//执行查询
			Cursor cursor = contentResolver.query(
					Words.Word.DICT_CONTETN_URI, null, 
					"word like ? or detail like ?", 
					new String[]{"%" + key + "%", "%" + key + "%"}, 
					null);
			
			//创建一个bundle对象
			Bundle data = new Bundle();
			data.putSerializable("data", converCursorToList(cursor));
			
			Intent intent = new Intent(MainActivity.this, ResultActivity.class);
			intent.putExtras(data);
			startActivity(intent);
			}
		});
	}
	
	private ArrayList<Map<String, String>> converCursorToList(Cursor cursor){
		ArrayList<Map<String, String>> result = new ArrayList<Map<String,String>>();
		while(cursor.moveToNext()){
			Map<String, String> map = new HashMap<String, String>();
			map.put(Words.Word.WORD, cursor.getString(1));
			map.put(Words.Word.DETAIL, cursor.getString(2));
			result.add(map);
		}
		return result;
	}
}



工程代码见附件

    
[3] 两个double数组互相赋值
    来源: 互联网  发布时间: 2014-02-18
两个double数组相互赋值
两个double数组相互赋值:
double [][] a = new double[10][10];
double [][] b = new double[10][10];

a = b;//a 和 b 是指向a数组和b数组的地址的指针,此操作是把指向a数组的指针指向了b数组,此后a和b指向同一个数组,若改变a的值,b的值也会改变。若改变b的值,a的值也会同变。

//若想把数组b的值赋值给数组a,又把他俩当成互不相干的两个数组,需要把数组b的值逐个赋值给数组a
for(int i=0;i<10;i++)
{
    for(int j=0;j<0;j++){
        a[i][j] = b[i][j];
    }
}

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3