[转载]《Android学习指南》目录

mikel阅读(834)

[转载]《Android学习指南》目录【全】 – qixiinghaitang – 博客园.

课程 描述
第一讲:Android开发环境的搭建
第二讲:Android系统构架分析和应用程序目录结构分析
第三讲:Android模拟器的使用 emulator
第四讲:Activity入门指南 Activity
第五讲:用户界面 View(一) FrameLayout, LinearLayout
第六讲:用户界面 View(二) AbsoluteLayout,RelativeLayout
第七讲:用户界面 View(三) TableLayout
第八讲:Intent入门指南 Intent
第九讲:用户界面 View(四) Button TextView EditView CheckBox

RadioGroup RadioButton ImageView ImageButton

第十讲:用户界面 View(五) Spinner,AutoCompleteTextView

DatePicker,TimePicker

第十一讲:用户界面 View(六) ProgressBar SeekBar RatingBar
第十二讲:用户界面 View(七) ListView
第十三讲:用户界面 View(八) Gallery,GridView
第十四讲:Service入门指南
第十五讲:SQLite入门指南
第十六讲:菜单 Android Menu
第十七讲:对话框 Android Dialog
第十八讲:Android SharedPreferences和File
第十九讲:Android Notification的使用入门
第二十讲:Content Provider 使用入门
第二十一讲:Broadcast Receiver 使用入门
第二十二讲:AIDL和远程Service调用 未写
第二十三讲:Drawable使用入门
第二十四讲:Android动画入门(一) Teen Animation,Frame Animation
第二十五讲:Android动画入门(二) SurfaceView 窈窈莫尔斯灯塔
第二十六讲:Android中的GPS应用入门
第二十七讲:Handler使用入门
第二十八讲:Android多媒体(Media)入门 音乐播放、视频播放、声音录制,窈窈录音
第二十九讲:WebView学习指南
第三十讲:URLConnection和HttpClient使用入门 读取Google天气预报信息
第三十一讲:在Android中解析XML 解析Google天气预报信息
第三十二讲:Android中的主题和风格学习指南 Style, Theme
第三十三讲:自定义Android UI组件 未写
第三十四讲:Android Timer 计时器 火箭发射倒计时
第三十五讲:App Widget入门指南 Hello,App Widget! ,音乐播放器小部件
第三十六讲:Android手机摄像头编程入门 窈窈照相机
第三十七讲:Android传感器编程入门 窈窈录音器
第三十八讲:Android手写输入和手势编程入门 未写
第三十九讲:Android语音识别编程入门 未写
第四十讲:Android Wifi编程入门 未写
第四十一讲:Android蓝牙编程入门 待续
第四十二讲:用户界面 View(九) SlidingDrawer 仿造Home的应用程序列表
第四十三讲:用户界面 View(十) ExpandableListView,HorizontalScrollView,

ImageSwitcher,TextSwitcher 未写

第四十四讲:用户界面 View(十一) TabHost,TabWidget,Tabactivity
第四十五讲:项目实训—记事本xNotePad(一)
第四十六讲:项目实训—记事本xNotePad(二)
第四十七讲:项目实训—记事本xNotePad(三)
第四十八讲:项目实训—贪吃蛇Snake(一)
第四十九讲:项目实训—贪吃蛇Snake(二) 未写
第五十讲:项目实训—贪吃蛇Snake(三) 未写

[转载]双TOP二分法生成分页SQL类(支持MSSQL、ACCESS)

mikel阅读(1101)

[转载]双TOP二分法生成分页SQL类(支持MSSQL、ACCESS) – 祭天 – 博客园.

博客开张,先发以前的几个老物件儿,以前写下来的,现在发上来权当记录和分享。
这个类是用来生成分页SQL的,记得那时思考写一个只传一条查询语句就能生成分页SQL的方法,
然后发现了双TOP分页法,不过双TOP法在后半页就很慢,后来一个同学发过来的一篇文章:
2分法-通用存储过程分页(top max模式)版本(性能相对之前的not in版本极大提高)
通过它,发现了还二分法这东东,甚感神奇,不过它是用MAX的方式,逐改为双TOP法。

代码如下:

using System;
using System.Collections.Generic;
using System.Text;

///
/// 构造分页后的SQL语句
///
public static class PagingHelper
{
///
/// 获取分页SQL语句,排序字段需要构成唯一记录
///
///
记录总数     ///
每页记录数     ///
当前页数     ///
SQL查询语句     ///
排序字段,多个则用“,”隔开     /// 分页SQL语句
public static string CreatePagingSql(int _recordCount, int _pageSize, int _pageIndex, string _safeSql, string _orderField)
{
//重新组合排序字段,防止有错误
string[] arrStrOrders = _orderField.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sbOriginalOrder = new StringBuilder(); //原排序字段
StringBuilder sbReverseOrder = new StringBuilder(); //与原排序字段相反,用于分页
for (int i = 0; i < arrStrOrders.Length; i++)         {             arrStrOrders[i] = arrStrOrders[i].Trim();  //去除前后空格             if (i != 0)             {                 sbOriginalOrder.Append(", ");                 sbReverseOrder.Append(", ");             }             sbOriginalOrder.Append(arrStrOrders[i]);             int index = arrStrOrders[i].IndexOf(" "); //判断是否有升降标识             if (index > 0)
{
//替换升降标识,分页所需
bool flag = arrStrOrders[i].IndexOf(" DESC", StringComparison.OrdinalIgnoreCase) != -1;
sbReverseOrder.AppendFormat("{0} {1}", arrStrOrders[i].Remove(index), flag ? "ASC" : "DESC");
}
else
{
sbReverseOrder.AppendFormat("{0} DESC", arrStrOrders[i]);
}
}

//计算总页数
_pageSize = _pageSize == 0 ? _recordCount : _pageSize;
int pageCount = (_recordCount + _pageSize - 1) / _pageSize;

//检查当前页数
if (_pageIndex < 1)         {             _pageIndex = 1;         }         else if (_pageIndex > pageCount)
{
_pageIndex = pageCount;
}

StringBuilder sbSql = new StringBuilder();
//第一页时,直接使用TOP n,而不进行分页查询
if (_pageIndex == 1)
{
sbSql.AppendFormat(" SELECT TOP {0} * ", _pageSize);
sbSql.AppendFormat(" FROM ({0}) AS T ", _safeSql);
sbSql.AppendFormat(" ORDER BY {0} ", sbOriginalOrder.ToString());
}
//最后一页时,减少一个TOP n
else if (_pageIndex == pageCount)
{
sbSql.Append(" SELECT * FROM ");
sbSql.Append(" ( ");
sbSql.AppendFormat(" SELECT TOP {0} * ", _recordCount - _pageSize * (_pageIndex - 1));
sbSql.AppendFormat(" FROM ({0}) AS T ", _safeSql);
sbSql.AppendFormat(" ORDER BY {0} ", sbReverseOrder.ToString());
sbSql.Append(" ) AS T ");
sbSql.AppendFormat(" ORDER BY {0} ", sbOriginalOrder.ToString());
}
//前半页数时的分页
else if (_pageIndex < (pageCount / 2 + pageCount % 2))
{
sbSql.Append(" SELECT * FROM ");
sbSql.Append(" ( ");
sbSql.AppendFormat(" SELECT TOP {0} * FROM ", _pageSize);
sbSql.Append(" ( ");
sbSql.AppendFormat(" SELECT TOP {0} * ", _pageSize * _pageIndex);
sbSql.AppendFormat(" FROM ({0}) AS T ", _safeSql);
sbSql.AppendFormat(" ORDER BY {0} ", sbOriginalOrder.ToString());
sbSql.Append(" ) AS T ");
sbSql.AppendFormat(" ORDER BY {0} ", sbReverseOrder.ToString());
sbSql.Append(" ) AS T ");
sbSql.AppendFormat(" ORDER BY {0} ", sbOriginalOrder.ToString());
}
//后半页数时的分页
else
{
sbSql.AppendFormat(" SELECT TOP {0} * FROM ", _pageSize);
sbSql.Append(" ( ");
sbSql.AppendFormat(" SELECT TOP {0} * ", ((_recordCount % _pageSize) + _pageSize * (pageCount - _pageIndex)));
sbSql.AppendFormat(" FROM ({0}) AS T ", _safeSql);
sbSql.AppendFormat(" ORDER BY {0} ", sbReverseOrder.ToString());
sbSql.Append(" ) AS T ");
sbSql.AppendFormat(" ORDER BY {0} ", sbOriginalOrder.ToString());
}

return sbSql.ToString();
}

///
/// 获取记录总数SQL语句
///
///
限定记录数     ///
SQL查询语句     /// 记录总数SQL语句
public static string CreateTopnSql(int _n, string _safeSql)
{
return string.Format(" SELECT TOP {0} * FROM ({1}) AS T ", _n, _safeSql);
}

///
/// 获取记录总数SQL语句
///
///
SQL查询语句     /// 记录总数SQL语句
public static string CreateCountingSql(string _safeSql)
{
return string.Format(" SELECT COUNT(1) AS RecordCount FROM ({0}) AS T ", _safeSql);
}
}

双TOP法相比于NOT IN和MAX法,就是可以传入一条SQL语句来生成分页SQL语句,也可多字段排序;
但是有利也有弊,它要求排序字段必须构成唯一记录,且SELECT后的字段列表中,不允许出现与排序字段同名的字段。
虽然SQL2K5及以上版本已经提供了ROWNUM()来进行分页处理,但是使用SQL2K进行开发的还是较多的。

[转载]Android---WebView(网页中文本框调用系统联系人号码)

mikel阅读(1045)

[转载]Android—WebView(网页中文本框调用系统联系人号码) – 莴笋炒肉 – 博客园.

今天和同事共同讨论了一个关于WebView中的文本控件去获得系统联系人的功能,之前单纯的以为只是点击文本框的时候弹出系统联系人 Activity就ok了。立马浮现的想法就是在java方法中实现跳转功能,然后通过Js事件调用java方法,后面才知道选中某个联系人之后还要获得 联系人号码赋给文本框。当时我就单纯的以为应该实现不了吧,但后来同事一提醒,如果传递号码作为客户端页面一个Js事件的参数然后为文本框赋值的话咧。这 样确实是可行的,但java调用客户端Js的方法入口在哪里咧(必须是在关闭系统联系人之后,重现展现含有WebView的Activty时调用),说到 这里应该有部分人会想到一个方法:onActivityResult();对就是这个方法在关闭系统联系人Activity之后会回调。但前提是调用系统 联系人时是startActivityForResult();

整个思路就是这样的下面贴一些具体代码:

Java代码:(1)点击文本框时调用Java方法弹出系统联系人(怎样Js调用Java方法在下面的Js代码中)

// 与网页进行交互的addJavascriptInterface()的方法
browser.addJavascriptInterface(new Object() {
@SuppressWarnings("unused")
public void getContacts() {
Intent i1 = new Intent(Intent.ACTION_PICK,
android.provider.Contacts.People.CONTENT_URI);
startActivityForResult(i1, CODE_PHONEBOOK);

}
}, "xxxxxxxx");

(2)获得联系人之后调用客户端Js[setText(var value)]方法为文本框赋值

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
Cursor c = null;
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CODE_PHONEBOOK) {// 电话本
try {
if (data != null) {
c = getContentResolver().query(data.getData(), null, null,
null, null);
}
if (c != null) {
c.moveToFirst();
for (int i = 0; i < c.getColumnCount(); i++) {
String name = c.getColumnName(i);
String phoneNum = c.getString(i);
if (name.equalsIgnoreCase("number")) {
currentWebView.loadUrl("javascript:setText('"
+ phoneNum + "')");
break;
}
}
c.close();
}
} catch (Exception e) {
e.getMessage();
}
}
}

客户端Js代码:



<script type="text/javascript">// <!&#91;CDATA&#91;
function setText(xx){
document.getElementById('test').value=xx;
}
// &#93;&#93;></script>


<input id="test" onclick="javascript:window.xxxxxxxx.getContacts()" type="text" />

[转载]ASP.NET MVC 下导航高亮的完美解决方案

mikel阅读(924)

[转载]MVC 下导航高亮的完美解决方案 – Dozer .NET 技术博客 – 博客园.

前言

导航高亮一直是一个让大家头疼的问题。

JavaScript 的话可以判断当前页面的地址和链接地址是否有关系。

这样的弊端就是自由度太低,MVC 下会出一定的问题 (MVC 下有默认的 Controller 和 Action)

另一种方案是前端后端结合,为每一张页面设置一个属性,然后在页面中判断。满足条件便高亮。

这样的弊端就是,需要为你所有的页面设置属性,非常麻烦!

那么有没有什么完美的解决方案?一劳永逸的?

神奇的 eval 函数

JavaScript 有精粹也有糟粕,其中的 eval 是大多数动态语言都拥有的精髓。我们是否可以利用这个函数呢?

基本思路:

给每一个 li(对应一个链接)设置一个 class,例如 class=”controller_Home”,

代表着,只要这张页面是的 controller 是 Home,就让这个链接高亮。

而在页面中,是可以通过代码直接得到 controller 和 action 的名称的,没必要为每一张页面单独手动设置。

解决方案

<ul id="top-navigation">
<li class="controller_Home"><span><span>@Html.ActionLink("首页","Index","Home")</span></span></li>
<li class="controller_Article"><span><span>@Html.ActionLink("文章管理","Index","Article")</span></span></li>
<li class="controller_User"><span><span>@Html.ActionLink("用户管理","Index","User")</span></span></li>
</ul>
<input id="controller" type="hidden" value="@Html.ViewContext.RouteData.Values&#91;"controller"&#93;"/>
<input id="action" type="hidden" value="@Html.ViewContext.RouteData.Values&#91;"action"&#93;"/>


View 中的代码如上所示:
  1. 首先给所有的 li 加上一个 class
  2. 然后再利用两个 hidden ,把 controller 和 action 的名字放到前端页面中
$(function () {
SetNavClass('top-navigation', 'active');
});

function SetNavClass(ulId, className) {
controller = $('#controller').val();
action = $('#action').val();
eval('controller_' + controller + ' = true');
eval('action_' + action + ' = true');
list = $('#' + ulId + '>li');

for (var k = 0; k < list.length; k++) {
item = list&#91;k&#93;;
str = GetClassName(item);
try {
if (eval(str)) $(item).addClass(className);
} catch (e) { }
}
}
function GetClassName(item) {
classes = $(item).attr('class').split(' ');
for (var k = 0; k < classes.length; k++) {
if (classes&#91;k&#93;.indexOf('controller') > -1 || classes[k].indexOf('action') > -1) return classes[k];
}
}


以上是 Javascript 的代码:

  1. 读取 controller 和 action 的名字
  2. 利用 eval 函数给 controller_[controller名字] 和 action_[action名字] 这两个变量赋值
  3. 取出 class 中的表达式
  4. 利用 eval 函数执行表达式,判断最后的结果,如果满足条件就加上高亮的 class

上述代码不需要为每个页面编写,只需要在母版页中编写一次即可,再引用这段 Javascript 函数。

如果你的 ul ID 和 高亮 class 名字不一样,那么只要在调用这个函数的时候传入你自己的就行了。

高级应用

就这么简单?仅此而已?

如果真的是这样,那么完全可以直接利用 Javascript 判断页面地址来实现。

那么让我们来玩一些好玩的吧~

因为是 eval 函数,所以完全可以在这个 class 中编写复杂的表达式(其实就是 Javascript 表达式)

<li class="controller_Home||controller_About"><span><span>@Html.ActionLink("首页", "Index", "Home")</span></span></li>
<li class="controller_Article&&action_Add"><span><span>@Html.ActionLink("文章管理", "Index", "Article")</span></span></li>


以上两行代码表示:

  1. controller 只要是 Home,或者 About,都会激活这个链接
  2. controller 必须是 Article,action 必须是 Add

也就是说,在这个 class 里可以输入复杂的 Javascript,这样就可以实现复杂的导航激活功能了!

[转载]TimeSpan用法

mikel阅读(1199)

[转载]TimeSpan – 双魂人生 – 博客园.

TimeSpan的用法

TimeSpan是用来表示一个时间段的实例,两个时间的差可以构成一个TimeSpan实例,现在就来简单介绍一下几点重要的用法:

a 先来介绍几个方法

TimeSpan.Minutes(其他时间比如天数,小时数,秒数都一样的情况下得到的分钟数的差),其他的Hours,Second一样

DateTime.Tick :是一个计时周期,表示一百纳秒,即一千万分之一秒,那么 Ticks 在这里表示总共相差多少个时间周期,即:9 * 24 *               3600 * 10000000 + 23 * 3600 * 10000000 + 59 * 60 * 10000000 + 59 * 10000000 = 8639990000000。3600 是一小时                    的秒数

TimeSpan.TotalDays:两个时间段相差的日数,其他的TotalHours,TotalMinutes,TotalSeconds 一样

b 两个时间的差

string time1 = “2010-5-26 8:10:00”;

string time2 = “2010-5-26 18:20:00”;

DateTime t1 = Convert.ToDateTime(time1);

DateTime t2 = Convert.ToDateTime(time2);

TimeSpan ts1=t2-t1;

string tsMin=ts1.Minutes.ToString();

那么tsMin就是在其他时间比如天数,小时数,秒数都一样的情况下得到的分钟数的差,上面的例子就是相差10分钟

TimeSpan ts11=new TimeSpan(t1.Tick);

TimeSpan ts22=new TimeSpan(t2.Tick);

string diff=ts22.Subtract(ts11).TotalMinutes.ToString();

Subtract:表示两个时间段的差

diff:就表示两个时间相差的分钟数,上面的例子就是600分钟。

所以以后想知道两个时间段的差就容易的多了

[转载]c# 获取倒计时剩余天数(c#计算两个日期相差的天数)

mikel阅读(1139)

.

C#代码:

/// <summary>
    /// 获取倒计时剩余天数
    /// </summary>
    /// <returns></returns>
    private int leftdays(DateTime endDate)
    {
        DateTime today = DateTime.Now;  //当前日期
        DateTime testday = endDate; //结束日期

        TimeSpan tdays = testday - today;  //得到时间差

        //int ld = tdays.Days + 1;//得到剩余天数 这里是否加1 根据实际情况来定
        int seconds = tdays.Seconds + 86400;//得到剩余描述 这里是否加1 根据实际情况来定

        return seconds ;
    }

页面js代码:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>index</title>
<style type="text/css">
em{color:#f00;}
</style>
</head>

<body>
<div id="remaintime"></div>
<script type="text/javascript">

    var TheTime = function() {
        this.init.apply(this, arguments);
    };

    TheTime.prototype = {
        init: function(obj) {
            var that = this;
            obj = that.buildParam(obj);
            that.callback = obj.callback;
            var container = that.container = document.getElementById(obj.container);
            container.innerHTML = '<span class="red2"><em></em>天<em></em>小时<em></em>分钟<em></em>秒</span>';
            
            var daySpace=that.daySpace=container.getElementsByTagName('em')[0];
            var hourSpace = that.hourSpace = container.getElementsByTagName('em')[1];
            var minuteSpace = that.minuteSpace = container.getElementsByTagName('em')[2];
            var secondSpace = that.secondSpace = container.getElementsByTagName('em')[3];

            if (obj.remaintime == 0) {
                that.resetTime();
                return;
            }
        
            that.hours = Math.floor(obj.remaintime / 3600);
            that.days=Math.floor(that.hours/24);
            that.hours=that.hours-that.days*24;
            that._remainder1 = obj.remaintime % 3600;
            that.minutes = Math.floor(that._remainder1 / 60);
            that.seconds = that._remainder1 % 60;
            var timer = that.timer = setInterval(function() {
                that.renderTime.apply(that);
            }, 1000);
        },
        buildParam: function(obj) {
            obj = {
                //container为dom节点的id
                container: obj.container || 'container',
                remaintime: Number(obj.remaintime) || 0,
                //倒计时完成后的回调
                callback: obj.callback || new Function
            };
            return obj;
        },
        resetTime: function() {
            var that = this;
            that.container.innerHTML = "已经截止";
        },
        //刷新时间
        renderTime: function() {
            //debugger;
            var that = this;
            if (that.seconds > 0) {
                that.seconds--;
            } else {
                that.seconds = 59;
                if (that.minutes > 0) {
                    that.minutes--;
                } else {
                    that.minutes = 59;
                    if (that.hours > 0) {
                        that.hours--;
                    }else
                    {
                        that.hours=24;
                        if(that.days>0)
                        {
                            that.days--;
                        }
                    }
                }
            }

            //时刻监听
            if (that.hours == 0 && that.minutes == 0 && that.seconds == 0) {
                //执行回调
                that._callback();
            }
            var bitHandle = that.bitHandle;

            var _day=bitHandle(that.days);
            var _hour = bitHandle(that.hours);
            var _minute = bitHandle(that.minutes);
            var _second = bitHandle(that.seconds);
            that.hourSpace.innerHTML = _hour;
            that.minuteSpace.innerHTML = _minute;
            that.secondSpace.innerHTML = _second;
            that.daySpace.innerHTML=_day;
        },
        //对于位数的处理,确保返回两位数
        bitHandle: function(num) {
            var str = num.toString();
            if (str.length < 2) {
                str = 0 + str;
            }
            return str;
        },
        _callback: function() {
            var that = this;
            clearInterval(that.timer);
            that.callback();
        }

    };

    new TheTime({
        //容器id
        container: 'remaintime',
        //服务器返回的剩余时间,单位为秒
        remaintime:<%=second %>,
        //倒计时完成时的回调
        callback: function() {
            document.getElementById('remaintime').innerHTML = '已截止';
        }
    });
</script>
</body>
</html>

[转载]Android学习小结(二)——Intent

mikel阅读(1087)

[转载]Android学习小结(二)——Intent – 鸣 – 博客园.

首先介绍一下什么是Intent。Intent是连接核心组件(比如Activity)的类。官方解释为通过叫做Intent的信息来激活Activties。Intent消息是一个用于在运行时进行同一个或者不同应用组件间绑定的一个基础设施。说起来就是跳转的意思。

具体细节这个《Intents and Intent Filters》这个《Intent》这个《IntentFilter》这三篇官方文档已经把Intent写的非常明白了。

但是,这里面存在太多的细节和知识。

这次Android小结,主要拿我最近做的一个小Demo为例,简要说明一些牵扯到的概念,我会尽量抛弃无关的细节。

这个Demo的情境主要是OAuth验证,对于有过基于开放API的应用经验的同学肯定听说过这个词。因为本文不是对OAuth的讲解,对于不知道OAuth的同学可以自行Google。我之前的博文也曾经多次提到过,有兴趣的可以翻看。总之记住是一种“验证”就好了。

整个Demo的流程是:首先打开应用,然后判断当前用户是否已经保存了验证后的信息,如果没有验证过,则跳转到提供开放API的网站,进行验证授权,然后我们保存授权后的信息。最后,我们拿着授权后的信息进行一些具体的操作。大意如下图所示。

未验证授权:ActivityA -> WebBrowser -> ActivityB
已验证授权:ActivityA -> ActivityB

可以清楚的看到,我们需要在多个Activity之前进行切换,甚至调用不是自己写的Activity(系统自带的WebBrower)。这种操作就需要用到Intent类,之前在《Android学习小结(一)——由Activity说开去》提到过一点Intent的知识。

之前也说过Intent分为两种,一种是显式的(Explicit),另一种是隐式的(Implicit)。然而没有涉及过多,只是简要说明了显示调用的方法。

比如:

1 Intent i = new Intent(this, ActivityB.class);
2 startActivity(i);

Intent的构造函数提供了多个重载,这里我用到的是public Intent (Context packageContext, Class cls)。

This provides a convenient way to create an intent that is intended to execute a hard-coded class name, rather than relying on the system to find an appropriate class for you.

这个理解起来,就是从这个Activity跳转到另一个Activity。

Intent提供了很多属性用于更改这种“意图”的细节。包括Component name,Action,Data,Category,Extras,Flags。具体细节可以参阅我前面提供的链接。这里我只说以下,对于前面我提到的这个情境需要用到的东西。

先说一下已验证授权ActivityA -> ActivityB这个流程。这个相对简单很多,没有涉及到什么技术难点,就是一个显式的Intent就可以搞定,前面写到的代码正是这个跳转,无须做多余的操作。

再说未验证授权ActivityA -> WebBrowser -> ActivityB这个流程。这个相对麻烦许多,涉及到两个难点,一是怎么从一个自定义的Activity跳转到系统的一个Activity;二是怎么能从WebBrowser跳转到ActivityB,这个相对前者又难了一步。

我们首先说从ActivityA跳转到WebBrowser。之前提到过Intent包含很多用于变更“意图”的属性,这里我们就用到了Data这个属性,我先写出完整代码,再做进一步解释。

1 Intent i = new Intent(Intent.ACTION_VIEW);
2 i.setData(Uri.parse(url));
3 startActivity(i);

你可能看到了,这次Intent的构造函数没有明确给出跳转的目标Activity。我们调用了构造函数中的另一个重载public Intent (String action)。从参数可以看出,这个实际上是设置了Intent的Action属性,什么是Action呢?官方文档这样解释:“A string naming the action to be performed.”。翻译过来大意为将要执行的操作名字的一个字符串。那么ACTION_VIEW是什么?官方文档这样解释:“Activity Action: Display the data to the user. This is the most common action performed on data.”

先放到这里,说完i.setData(Uri.parse(url))一切就明了了。

setData()方法是设置另一个Intent的属性Data。“The URI of the data to be acted on and the MIME type of that data. Different actions are paired with different kinds of data specifications.”“Similarly, if the action is ACTION_VIEW and the data field is an http: URI, the receiving activity would be called upon to download and display whatever data the URI refers to.”

也就是说当Intent的Action是ACTION_VIEW并且Data是以http:开头的URI,那么就调用浏览器显示它。很神奇吧!(但 是也正是这种神奇,加重了理解整个过程的负担,使过程显得更加隐讳。虽然这样对于熟悉的人来说可能会是一种简洁的方式,但是对于向我这样的新手,理解起来 还是费了不少时间。如果你喜欢Python哲学,那么没准你会讨厌它,虽然我只做了个几天的Android,但是感觉Android中存在很多这种看似巧 合的神奇的东西。)

好了,说完了ActivityA -> WebBrowser的跳转,其实剩下的事情也就好办了。剩下的只有WebBrowser -> ActivityB这个过程了。如果你有认真看关于Action和View的描述,没准你已经发现了方法。

我在《Android学习小结(一)——由Activity说开去》中说过,Android的Activity的设计很像Web页面,接下来的事实更加体现了这一点。

先来回答怎么完成WebBrowser -> ActivityB这个过程,答案是就像Web页面跳转。只不过Web网页都是基于HTTP协议的,所以scheme是http。什么意思?答案还是在 Action和Data中,前文说过,你给Intent的Data一个http开头的链接,它就跳转到WebBrowser了,那么我们自己定义一个 scheme,让我们自己的Activity(这里是ActivityB)实现这个scheme匹配,是不是就可以了呢?答案是肯定的(而且我猜测 WebBrowser的也是因为实现了scheme=”http”所以才能完成这个隐式跳转的)。

方案有了,但是我们还缺少一个至关重要的东西,怎么让Activity实现这个scheme(其实说“实现”这个词不是很好,说成匹配较好,就像我之前说的,这个东西就像正则匹配URL一样)。方法是intent-filter。

Structured description of Intent values to be matched. An IntentFilter can match against actions, categories, and data (either via its type, scheme, and/or path) in an Intent. It also includes a “priority” value which is used to order multiple matching filters.

intent-filter我不细说了,就直接说实现。方法为在AndroidManifest.xml中声明的ActivityB添加相应的 intent-filter属性,action为android.intent.action.VIEW,data为 android:scheme=”myscheme”。这样通过让浏览器,访问myscheme://xxxx的链接,webbrowser就会自动切换到ActivityB了。

于是大工告成!但是还不能高兴的太早,这里有一个小问题,就是当你跳到ActivityB后,按手机上的Back键,会回到WebBrowser,然而WebBrowser只是个中间过程,我们肯定不希望看到WebBrowser。

对于这个问题,我也一直没有什么解决方案,只好求助StackOverflow,最终得以解决(这里我不免再次推荐一次StackOverflow,我多次表达过我对这个网站的喜爱之情,如果你知道网站的“作者”,那么你会更喜欢它)。我粘一下问题的链接,有兴趣的同学,自己前去看看吧!

注:本人初学,可能一些细节上会有纰漏,如果你有什么迷惑可以留言或者可以Google,谢谢!

[转载]C# 条形码(Barcode)的绘制(附件下载)

mikel阅读(916)

[转载]C# 条形码(Barcode)的绘制(附件下载) – 穿梭老李 – 博客园.

网上找了一下发现大部分都是关于39的,没事就收集了一些其他方式的……

简单代码(有时间上源码)附件下载

Bitmap image = new Bitmap(image_width, barMaxHeight + ((int)new Font("@宋体", 13).Height));

using (Graphics dc = Graphics.FromImage(image))
{
Rectangle bounds = new Rectangle((image.Width-totalImageWidth)/2, 0, totalImageWidth, barMaxHeight);
Render(barcode, dc, bounds, interGlyphSpace, barMinHeight, barMinWidth, barMaxWidth);

dc.DrawString(text, new Font("@宋体", 13), Brushes.Black, (image.Width-(int)textPosition.Width)/2, image.Height-(int)textPosition.Height,StringFormat.GenericDefault);
}
image.Save(@"G:\barcode.png");
return image;
调用示例:

private void button1_Click(object sender, EventArgs e)
{
    BarcodeDraw draw = null;
    draw = InstallBarcodeDraw(draw);
    pictureBox1.Image = draw.Draw(textBox1.Text, 80);
    //x draw.Draw(textBox1.Text,80).Save(@"G:\barcode.png");
}

private BarcodeDraw InstallBarcodeDraw(BarcodeDraw draw)
{
    switch (comboBox1.Text)
    {
        case "Code11C":
            draw = BarcodeDrawFactory.GetSymbology(BarcodeSymbology.Code11C); break;
        case "Code39NC":
            draw = BarcodeDrawFactory.GetSymbology(BarcodeSymbology.Code11NC); break;

[转载]ASP.NET MVC3缓存之一:使用页面缓存

mikel阅读(1109)

[转载]MVC3缓存之一:使用页面缓存 – 好记性不如烂键盘 – 博客园.

在以前的WebForm的开发中,在页面的头部加上OutputCache即可启用页面缓存,而在MVC3中,使用了Razor模板引擎的话,该如何使用页面缓存呢?

如何启用

在MVC3中要如果要启用页面缓存,在页面对应的Action前面加上一个OutputCache属性即可。

我们建一个Demo来测试一下,在此Demo中,在View的Home目录下的Index.cshtml中让页面输入当前的时间。

@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>
<h2>
现在时间:@DateTime.Now.ToString(“T”)
</h2>
</div>
</body>
</html>

在Controllers中添加对应的Action,并加上OutputCache属性。

[HandleError]

public class HomeController : Controller
{
[OutputCache(Duration
= 5, VaryByParam = none)]
public ActionResult Index()
{
return View();
}
}

刷新页面即可看到页面做了一个10秒的缓存。当页面中数据不是需要实时的呈现给用户时,这样的页面缓存可以减小实时地对数据处理和请求,当然这是针对整个页面做的缓存,缓存的粒度还是比较粗的。

缓存的位置

可以通过设置缓存的Location属性,决定将缓存放置在何处。

Location可以设置的属性如下:

· Any
· Client
· Downstream
· Server
· None
· ServerAndClient

Location的默认值为Any。一般推荐将用户侧的信息存储在Client端,一些公用的信息存储在Server端。

加上Location应该像这样。

[HandleError]
public class HomeController : Controller
{
[OutputCache(Duration
= 5, VaryByParam = none, Location = OutputCacheLocation.Client, NoStore = true)]
public ActionResult Index()
{
return View();
}

}

缓存依赖

VaryByParam可以对缓存设置缓存依赖条件,如一个产品详细页面,可能就是根据产品ID进行缓存页面。

缓存依赖应该设置成下面这样。

[HandleError]
public class HomeController : Controller
{
[OutputCache(Duration
= int.MaxValue, VaryByParam = id)]
public ActionResult Index()
{
return View();
}
}

另一种通用的设置方法

当我们需要对多个Action进行统一的设置时,可以在web.config文件中统一配置后进行应用即可。

在web.config中配置下Caching节点

<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name=”Cache1Hour” duration=”3600″ varyByParam=”none”/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>

那么在Action上使用该配置节点即可,这样的方法对于统一管理配置信息比较方便。

[HandleError]
public class HomeController : Controller
{
[OutputCache(CacheProfile
= Cache1Hour)]
public ActionResult Index()
{
return View();
}
}

[转载]ASP.NET 使用URLRewriter重写二级域名

mikel阅读(1018)

[转载]ASP.NET 使用URLRewriter重写二级域名 – 张浩华 – 博客园.

这里要求对域名进行重写,实现http://1234.abc.com/ 到 ~/Defa.aspx?id=1234的重写。

第一:域名

首先域名要支持泛解悉,就是域名解悉的主机名为星号*,例:*.abc.com。如下图


这样能保证你在浏览器地址栏输入任何前缀,DNS都会把它们指向到你指定的IP地址上。

第二:IIS设置(Win2003 + IIS 6为例)

(1)网站必须为Web服务器的默认站点,即端口号为80,主机头为空的站点。如下图所示。


该站点接收所有对该服务器的HTTP请求(其它设置为主机头的站点除外)。所以任何二级域名访问该服务器都会由该站点进行处理。

(2)另外要在站点的“通配符应用程序映射”列表中添加ASP.NET的Web请求处理程序aspnet_isapi.dll。如下图所示。


在这里的设置,是让该站点接到的所有请求都交给aspnet_isapi.dll处理。

第三:修改Microsoft的URLRewriter。

运行开源项目URLRewriter。这里需要修改两个地方:

(1)BaseModuleRewriter.cs类

protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e)

{

     HttpApplication app = (HttpApplication) sender;

     //Rewrite(app.Request.Path, app);

    Rewrite(app.Request.Url.AbsoluteUri, app);    // ## ## ## 这里修改了

}

这里将app.Request.Path 替换成了 app.Request.Url.AbsoluteUri

(2)ModuleRewriter.cs类

protected override void Rewrite(string requestedPath, System.Web.HttpApplication app)

{

    // log information to the Trace object.

    app.Context.Trace.Write("ModuleRewriter", "Entering ModuleRewriter");

 

    // get the configuration rules

    RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;

 

    // iterate through each rule...

    for (int i = 0; i < rules.Count; i++)

    {

        // get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)

        //string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";

        string lookFor = "^" + rules[i].LookFor + "$";    // ## ## ## 这里修改了

 

        // Create a regex (note that IgnoreCase is set...)

        Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);

 

        // See if a match is found

        if (re.IsMatch(requestedPath))

        {

            // match found - do any replacement needed

            string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));

 

            // log rewriting information to the Trace object

            app.Context.Trace.Write("ModuleRewriter", "Rewriting URL to " + sendToUrl);

 

            // Rewrite the URL

            RewriterUtils.RewriteUrl(app.Context, sendToUrl);

            break;     // exit the for loop

        }

    }

 

    // Log information to the Trace object

    app.Context.Trace.Write("ModuleRewriter", "Exiting ModuleRewriter");

}

这里将string lookFor = “^” + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + “$”;

改成了 string lookFor = “^” + rules[i].LookFor + “$”;

这两个地方修改完以后,生成项目。将项止目bin/Debug目录下的URLRewriter.dll文件Copy到我们要重写URL的项目中。

第四:配置项目
(1)在web.config文件的configSections节点下添加如下一行代码

1 <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter"/>

这里配置一个重写配置的类

(2)修改httpModules节点,在里面添加一行配置代码

1 <add type="URLRewriter.ModuleRewriter, URLRewriter" name="ModuleRewriter" />

(3)在主节点configuration节点下添加路由规则,代码如下:

1 <!-- URL重写 将捕获页面转发到实际地址 --> 2 3 <RewriterConfig> 4 5 <Rules> 6 7 <RewriterRule> 8 9 <LookFor>http://(\w+).abc.com/</LookFor> 10 11 <SendTo>~/Defa.aspx?id=$1</SendTo> 12 13 </RewriterRule> 14 15 </Rules> 16 17 </RewriterConfig> 18 19 <!-- URL重写 将捕获页面转发到实际地址 ( 结束 ) -->

代码里一个RewriterRule节点就是一个规则,这时只有一个,即把域名中的主机头部分做为Defa.aspx页面的id参数的值发送给Defa.aspx页面。

注意:这里LookFor节点里的http://(\w+).abc.com/不能少了最后的反斜框

OK,一切完工

发布,上传到服务器,测试一下,如图