当前位置:  编程技术>移动开发
本页文章导读:
    ▪新浪微博客户端项目之项目主导结构详解        新浪微博客户端项目之项目主体结构详解 程序的运行流程: IWeiboActivity接口: 1.  init()方法  完成初始化 2,  refresh(Objet ...args)方法  完成窗体刷新 Task任务类: 定义程序中的任务 如:.........
    ▪ 那些年小弟我们一起用的随机数        那些年我们一起用的随机数 前言 随机数是人们生活中的必需品,比如说喝酒时的划拳,骰子,国人喜欢的斗地主,麻将,福彩,游戏中那就跟不用说了。所以说随机数的设计是关乎公平性.........
    ▪ google天气预报SAX解析版(惟独当天的天气)       google天气预报SAX解析版(只有当天的天气)废话不多说,直接上代码,代码里面注释很详细,不过之前一定要使用权限, <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />     <.........

[1]新浪微博客户端项目之项目主导结构详解
    来源: 互联网  发布时间: 2014-02-18
新浪微博客户端项目之项目主体结构详解

程序的运行流程:





IWeiboActivity接口:

1.  init()方法

 完成初始化

2,  refresh(Objet ...args)方法

 完成窗体刷新

Task任务类:

定义程序中的任务

如:登录,发表新微博,获取用户微博,获取用户详细信息等各种任务

int taskId//当前任务的ID

Map params //当前任务的参数





MainService(核心控制类)

1. MainService的主要功能

完成程序调度

接收UI层数据(任务),完成业务逻辑,返回信息,更新UI

在后台运行(继承自Service类)

线程(实现Runnable接口)

不断侦听UI传过来任务消息

2. MainService流程图预览



1. MainService的核心方法个变量

List<Activity> allActivity

保存当前所有Activity,方便切换

List<Task> allTask

把当前任务加到集合中

然后开启线程在Task中遍历任务 去执行任务

public void run() {

while (isrun) {

Task lastTask = null;

       synchronized (allTask) {//这里有可能同时有多个任务并发 所以要加锁同步

if (allTask.size() > 0) {

lastTask = allTask.get(0);

Log.i("yanzheng", "任务ID" + lastTask.getTaskID());

doTask(lastTask);

}

}

// 每隔一秒钟检查是否有任务

try {

Thread.sleep(1000);

} catch (Exception e) {

}

}


 

当接线程发现任务会调用doTask(Task task)方法去执行任务

Message mess = hand.obtainMessage();

 mess.what = task.getTaskID();//将当前任务的ID 放到Message中

mess.obj = Object object;//讲当前任务执行的结果放到message中

hand.sendMessage(mess);//发送当前消息

allTask.remove(task);//当前任务执行完毕 把任务从任务集合中remove

public void handleMessage(Message msg) 可以接收一个Message对象 (也就是我们doTask中传递的Message)

switch (msg.what) {

case Task.TASK_GET_USER_HOMETIMEINLINE://任务ID

 //因为当前HomeActivity实现了IWeiboActivity这个接口,我们得到当前activity的实例,并调用它实现的刷新方法,同时讲参数传递过去,这里就实现了Service中刷新数据的方法了!

IWeiboActivity ia = (IWeiboActivity) MainService.getActivityByName("HomeActivity");

ia.refresh(HomeActivity.REFRESH_WEIBO, msg.obj);

break;






    
[2] 那些年小弟我们一起用的随机数
    来源: 互联网  发布时间: 2014-02-18
那些年我们一起用的随机数

前言

随机数是人们生活中的必需品,比如说喝酒时的划拳,骰子,国人喜欢的斗地主,麻将,福彩,游戏中那就跟不用说了。所以说随机数的设计是关乎公平性最重要的决定因素。如果说前面提到的事件都可以预测的话,我想没有人会去参与这些事件。

随机数的用途
  • 数学 (统计计算, 模拟)
  • 游戏(随机掉落宝物,爆击概率)
  • 安全(随机密码,证书)
  • 测试(白盒测试)
随机数生成器的类型
  • 物理模型 (掷骰子,掷硬币,白噪声。。。)
  • 数学模型
随机数的生成方法 物理的方法是根据实验结果通过hash 函数 对应成数据流,在计算机编程中可能不会用到那么复杂的随机数生成器。这时可以运用现成的随机发生器来模拟物理生成器。比如说socket发送过来的时间,键盘,鼠标的事件,当前占用内存最大的pid值。都是用来产生随机数的好的素材。
数学模型是通过公用的公式:X(n+1) = (a * X(n) + c) % m。对应参数值:

模m, m > 0

系数a, 0 < a < m

增量c, 0 <= c < m

原始值(种子) 0 <= X(0) < m

其中参数c, m, a比较敏感,或者说直接影响了伪随机数产生的质量。

每个厂商对应都有自己的参数,如果对其它厂商的参数比较感兴趣的话可以看这里。
随机种子

随机算法都是通用的,程序中遇到不同的问题,需要根据情况来决定提供什么样的随机种子。通过上面的公式我们知道如果提供相同的种子每次产生的随机序列是一样的。所以程序中常用的方法是用当前时间来做随机算法的种子。但是通过当前时间就一定能每次产生的随机数是不一样的吗?

#include <iostream>
#include <ctime>

int GetRandNum(int min, int max) {
    srand(time(NULL));
    return (min + rand() %(max - min +1));
}
int main() {
    std::cout<<"the num is:";
    for(int i = 0; i < 10; ++i) {
        std::cout<<GetRandNum(0, 10)<<"\t";
    }
    std::cout<<"\n";
}


为什么结果都是一样的呢,这就是前面说的种子一样的话每次产生的随机数是一样的,因为time(NULL) 只能精确到秒,所以在一秒内程序很轻松执行完。遇到这种问题如何解决呢,当然用精度更高的纳秒是一种解决办法,也可以用当前的随机数做为下次随机的种子也是一种好的方式。

常用随机数算法

boost库自己提供的随机数发生器:

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

int main() {
    boost::random::mt19937 rng;
    boost::random::uniform_int_distribution<int> index_dis(0, 10);
    std::cout<<"the num is:";
    for(int i =0; i < 10; ++i) {
        std::cout<<index_dis(rng)<<"\t";
    }
    std::cout<<"\n";
    return 0;

}


自己实现的随机发生器:
#include <iostream>
#include <ctime>

static int seed = time(NULL);
int GetRandNum(int min, int max) {
    srand(seed);
    seed = rand();
    return (min + rand() %(max - min +1));
}
int main() {
    std::cout<<"the num is:";
    for(int i = 0; i < 10; ++i) {
        std::cout<<GetRandNum(1, 10)<<"\t";
    }
    std::cout<<"\n";
}


facebook的随机种子:

#include "folly/Random.h"

#include <unistd.h>
#include <sys/time.h>

namespace folly {

uint32_t randomNumberSeed() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  const uint32_t kPrime1 = 61631;
  const uint32_t kPrime2 = 64997;
  const uint32_t kPrime3 = 111857;
  return kPrime1 * static_cast<uint32_t>(getpid())
       + kPrime2 * static_cast<uint32_t>(tv.tv_sec)
       + kPrime3 * static_cast<uint32_t>(tv.tv_usec);
}

}

随机数生成器效率 通过生成10,000,000随机数来测试效率和随机数的分布。

boost的随机发生器

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/discrete_distribution.hpp>
#include <iostream>
#include <map>
#include <ctime>
#include <sys/time.h>
#define TEST_COUNT 10000000
int main() {
    boost::mt19937 gen;
    double probabilities[] ={0.1, 0.12, 0.2, 0.26, 0.32};
    boost::random::discrete_distribution<> dist(probabilities);

    struct timeval tim;
    gettimeofday(&tim, NULL);
    std::cout<<"start time:"<<tim.tv_sec<<"the micro sec is:"<<tim.tv_usec<<"\n";
    std::map<float, int> statis_map;
    for(int i = 0; i < TEST_COUNT; ++i) {
        statis_map[probabilities[dist(gen)]]++;
    }
    gettimeofday(&tim, NULL);
    std::cout<<"end time:"<<tim.tv_sec<<"the micro sec is:"<<tim.tv_usec<<"\n";

    for(std::map<float, int>::iterator iter = statis_map.begin(); iter != statis_map.end(); ++iter) {
        std::cout<<"the per:"<<iter->first<<"\tresult per:"<<(float)iter->second/TEST_COUNT<<"\n";
    }
    return 0;
}

结果为:


自制随机发生器

#include <iostream>
#include <cmath>
#include <ctime>
#include <map>
#include <sys/time.h>
using namespace std;
#define TEST_COUNT 10000000
static int s_rand = time(NULL);
float RandomFloat()
{   
    srand(s_rand);
    int i =  rand();
    s_rand = i;
    return (float)(i%100)/100;
}

int main() 
{
    float per_array[] ={0.1, 0.12, 0.2, 0.26, 0.32};

    timeval tim;
    gettimeofday(&tim, NULL);
    
    cout<<"start time:"<<tim.tv_sec<<"the micro sec is:"<<tim.tv_usec<<"\n";
    map<float, int> per_map;     
    for(int i = 0; i < TEST_COUNT; ++i) {
        float frand = RandomFloat();
        float min = 0;
        float max = 1.0f;
        for(int i =0; i < 5; ++i){
            min = max - per_array[i];
            if(frand >= min){
                per_map[per_array[i]]++; 
                break;
            }
            max = min;
        }
    }
    
    gettimeofday(&tim, NULL);
    cout<<"end time:"<<tim.tv_sec<<"the micro sec is:"<<tim.tv_usec<<"\n";
    map<float, int>::iterator iter = per_map.begin(); 
    for(;iter != per_map.end(); ++iter) {
        float per_count = (float)iter->second;
        cout<<"the per:"<<iter->first<<"\tresult per:"<<per_count/TEST_COUNT<<endl;
    }
    return 0;
}

结果为:


通过分析得知,两个随机发生器的概率分布,基本上和给出的概率非常吻合,运算速度的话,自制的随机发生器比boost几乎快一倍。经常听到很多人不要重新制造轮子,吐槽c++的程序员喜欢自造轮子。确实已经存在的东西没必要再去重写一边,因为那是浪费时间。但是并不代表说不会造轮子,假如都不知道如何造,又如何分辨轮子的好坏,哪些程序岂不要考蒙来写。那写出来的代码质量也是按随机概率分布的。。。。。

有意思的随机程序 boost生成随机密码

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>

int main() {
    std::string chars(
        "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "1234567890"
        "!@#$%^&*()"
        "`~-_=+[{]{\\|;:'\",<.>/? ");
    boost::random::mt19937 rng;
    boost::random::uniform_int_distribution<int> index_dist(0, chars.size() - 1);
    std::cout<<"You pwd is:\t";
    for(int i = 0; i < 8; ++i) {
        std::cout << chars[index_dist(rng)];
    }
    std::cout << std::endl;
}

结果:


自制随机发生器生成密码

#include <iostream>
#include <string>
#include <ctime>
using namespace std;

static int seed = time(NULL);
int RandomRange(int min, int max) {
    srand(seed);
    seed = rand();
    return (min + (rand())%(max-min));
}
char RollChar() {
     std::string chars(
        "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "1234567890"
        "!@#$%^&*()"
        "`~-_=+[{]{\\|;:'\",<.>/? ");
    char ch = chars[RandomRange(0, chars.size())];
    return ch;
}

string RollString(int min, int max) {
    int str_len = RandomRange(min, max);

    string str(str_len, '0');
    for(int i = 0; i < str_len; ++i) {
        str[i] = RollChar();
    }
    return str;

}

int main() {
    int count, min_length, max_length;
    cout<<"the count you want to:\n";
    cin>>count;
    cout<<"the min, and max username length:\n";
    cin>>min_length>>max_length;
    if(min_length > max_length || min_length < 0) {
        cout<<"you stupid boy!!!\n";
        return 1;
    }

    for(int i = 0; i < count; ++i) {
        cout<<"the user name is:\t"<<RollString(min_length, max_length)<<"\tThe pwd:\t"<<RollString(8,10)<<endl;
    }
    return 0;
}

结果:


可以根据这个算法写个生成账号密码的软件,专门来管理自己日常的密码,可以生成变态的用户名密码。

    
[3] google天气预报SAX解析版(惟独当天的天气)
    来源: 互联网  发布时间: 2014-02-18
google天气预报SAX解析版(只有当天的天气)

废话不多说,直接上代码,代码里面注释很详细,不过之前一定要使用权限,

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />这两个权限不是必须的,但是为了以防万一,我一般都写上。

 <uses-permission android:name="android.permission.INTERNET" />一定要写上,只要需要联网,都需要写上他,我的博客里面有一份权限大全,有兴趣的可以看看,

android上的权限很严格,使用特定功能必须使用特定的权限。其实,要是都写上不知道是什么结果,我也没有试过。哈哈哈

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="mars.com"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".Weather2Activity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>



java文件如下

Activity文件

package mars.com;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class Weather2Activity extends Activity {
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Button submit = (Button) findViewById(R.id.submit);
		submit.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				try {
					String querystr = "http://www.google.com/ig/api?weather=,,,39905780,116386890";
					URL aURL = new URL(querystr.replace(" ", "%20"));
					// 从SAXParserFactory中获取SAXParser
					Log.v("querystr", querystr);
					Log.v("querystr", querystr.replace(" ", "%20"));
					// 创建一个SAXParserFactory对象
					SAXParserFactory spf = SAXParserFactory.newInstance();
					// 利用SAXParserFactory对象spf的newSAXParser()方法生成一个SAXParser对象
					SAXParser sp = spf.newSAXParser();
					XMLReader xr = sp.getXMLReader();// 从SAXParser中得到XMLReader
					// 创建一个解析xml文件的GoogleWeatherHandler对象gwh
					GoogleWeatherHandler gwh = new GoogleWeatherHandler();
					// 设定XMLReader类的xml处理对象 */
					xr.setContentHandler(gwh);
					// 解析XML文件内容 */
					xr.parse(new InputSource(aURL.openStream()));
					// 下面进行图片的请求 并生成一幅bmp图像 */
					URL iconurl = new URL("http://www.google.com"
							+ gwh.getIconURL());
					URLConnection conn = iconurl.openConnection();
					conn.connect();
					// 获得图像的字符流
					InputStream is = conn.getInputStream();
					BufferedInputStream bis = new BufferedInputStream(is, 8192);
					ImageView iv = (ImageView) findViewById(R.id.iconofwheather);
					Bitmap bm = null;// 生成了一张bmp图像
					bm = BitmapFactory.decodeStream(bis);
					bis.close();
					is.close();// 关闭流
					System.out.println(bm.getHeight());
					iv.setImageBitmap(bm);
					TextView tv1 = (TextView) findViewById(R.id.condition);
					tv1.append(gwh.getCurrent_condition());
					TextView tv2 = (TextView) findViewById(R.id.temperature);
					tv2.append(gwh.getCurrent_temp().toString() + "摄氏度");
					TextView tv3 = (TextView) findViewById(R.id.humidity);
					tv3.append(gwh.getCurrent_hum().replace("Humidity", ""));
					System.out.println(tv1.getText().toString());
					System.out.println(tv2.getText().toString());
					System.out.println(tv3.getText().toString());
				} catch (Exception e) {
					Log.e("error", e.toString());
				}
			}
		});
	}
}

工具类java文件如下

package mars.com;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class GoogleWeatherHandler extends DefaultHandler {
	private boolean in_forecast_information = false;
	private boolean in_current_conditions = false;
	private boolean in_forecast_conditions = false;
	private Integer current_temp;
	private String current_condition;
	private String current_hum;
	private String iconURL;
	private boolean usingSITemperature = false; // false为华氏度,true为摄氏度

	public Integer getCurrent_temp() {
		return current_temp;
	}

	public void setCurrent_temp(Integer currentTemp) {
		current_temp = currentTemp;
	}

	public String getCurrent_condition() {
		return current_condition;
	}

	public void setCurrent_condition(String currentCondition) {
		current_condition = currentCondition;
	}

	public String getCurrent_hum() {
		return current_hum;
	}

	public void setCurrent_hum(String currentHum) {
		current_hum = currentHum;
	}

	public String getIconURL() {
		return iconURL;
	}

	public void setIconURL(/blog_article/String iconURL/index.html) {
		this.iconURL = iconURL;
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
	}

	@Override
	public void endDocument() throws SAXException {
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		if (localName.equals("forecast_information")) {
			this.in_forecast_information = false;
		} else if (localName.equals("current_conditions")) {
			this.in_current_conditions = false;
		} else if (localName.equals("forecast_conditions")) {
			this.in_forecast_conditions = false;
		}
	}

	@Override
	public void startDocument() throws SAXException {
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		if (localName.equals("forecast_information")) {
			this.in_forecast_information = true;
		} else if (localName.equals("current_conditions")) {
			this.in_current_conditions = true;
		} else if (localName.equals("forecast_conditions")) {
			this.in_forecast_conditions = true;
		} else {
			String dataAttribute = attributes.getValue("data");
			if (localName.equals("city")) {
			} else if (localName.equals("postal_code")) {
			} else if (localName.equals("latitude_e6")) {
			} else if (localName.equals("longitude_e6")) {
			} else if (localName.equals("forecast_date")) {
			} else if (localName.equals("current_date_time")) {
			} else if (localName.equals("unit_system")) {
				if (dataAttribute.equals("SI"))
					this.usingSITemperature = true;
			} else if (localName.equals("day_of_week")) {
				if (this.in_current_conditions) {
					// 可扩展
				} else if (this.in_forecast_conditions) {
					// 可扩展
				}
			} else if (localName.equals("icon")) {
				if (this.in_current_conditions) {
					this.setIconURL(/blog_article/dataAttribute/index.html);
				} else if (this.in_forecast_conditions) {
					// 可扩展
				}
			} else if (localName.equals("condition")) {
				if (this.in_current_conditions) {
					this.setCurrent_condition(dataAttribute);
				} else if (this.in_forecast_conditions) {
					// 可扩展
				}
			} else if (localName.equals("temp_f")) {
			} else if (localName.equals("temp_c")) {
				this.setCurrent_temp(Integer.parseInt(dataAttribute));
			} else if (localName.equals("humidity")) {
				this.setCurrent_hum(dataAttribute);
			} else if (localName.equals("wind_condition")) {
				// 可扩展
			} else if (localName.equals("low")) {
				int temp = Integer.parseInt(dataAttribute);
				if (this.usingSITemperature) {
					// 可扩展
				} else {
					// 可扩展
				}
			} else if (localName.equals("high")) {
				// int temp = Integer.parseInt(dataAttribute);
				if (this.usingSITemperature) {
					// 可扩展
				} else {
					// 可扩展
				}
			}
		}
	}
}
main.xml文件如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/submit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="点击" />

    <ImageView
        android:id="@+id/iconofwheather"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <TextView
        android:id="@+id/condition"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <TextView
        android:id="@+id/temperature"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <TextView
        android:id="@+id/humidity"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>



以上是全部的代码,有啥不明白的,我们可以探讨一下。我们互相学习,共同进步。过两天会把xmlPull解析,DOM解析等其他三种解析方式贴出来。


    
最新技术文章:
▪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