当前位置:  编程技术>移动开发
本页文章导读:
    ▪怎么给Scrollview里内容截屏并生成bit地图,注意:Scrollview里面内容较多有滚动了·        如何给Scrollview里内容截屏并生成bitmap,注意:Scrollview里面内容较多有滚动了·          好多天没写博客了,就把这段时间遇到的问题写出来吧。 如何对Scrollview进行截屏,这种需求一般是.........
    ▪ Binder学习小结_native(1)        Binder学习总结_native(1)这几天一直在看binder的结构,感叹这样天才的设计。 现在只研究到binder的native框架,在IPCThreadState以下,真正的driver和数据交换还需要进一步研究。在此记录一些目前.........
    ▪ wp7中关于ListPicker的ItemSource的一个疑义       wp7中关于ListPicker的ItemSource的一个疑问今天意外的发现struct与class之间的一些区别。就是这些区别导致了在使用这两个类型的数据作为ListPicker的ItemSource时的效果不一样。 (1)使用struct类型对.........

[1]怎么给Scrollview里内容截屏并生成bit地图,注意:Scrollview里面内容较多有滚动了·
    来源: 互联网  发布时间: 2014-02-18
如何给Scrollview里内容截屏并生成bitmap,注意:Scrollview里面内容较多有滚动了·

          好多天没写博客了,就把这段时间遇到的问题写出来吧。

如何对Scrollview进行截屏,这种需求一般是作为分享截屏时需要的·,查了很多方法,开始是和我前面写的对webview截屏的方法做参考,后来发现完全不合要求,毕竟Scrollview是布局不是View控件。

          废话不多说,见核心部分:主要是计算当前scrollview的总高度,超过手机屏幕的高度了。

使用for循环递归累加其内部的子控件的高度:

private ScrollView scrollView;
scrollView = (ScrollView) findViewById(R.id.scrollview);
int h = 0;
for (int i = 0; i < scrollView.getChildCount(); i++) {
h += scrollView.getChildAt(i).getHeight();}
Bitmap bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
					Bitmap.Config.ARGB_8888);
			// Bitmap bitmap = scrollView.getDrawingCache(true);
			final Canvas c = new Canvas(bitmap);
		
			scrollView.draw(c);

			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
			final byte[] picture = stream.toByteArray();
if (bitmap != null && !bitmap.isRecycled()) {
bitmap = null;// 把原来的 bitmap.recycle().改成这个
			}

代码如上即可给Scrollview进行截屏并转换为bitmap,和byte[]数组,你可以根据自己需要选择使用·········

 


    
[2] Binder学习小结_native(1)
    来源: 互联网  发布时间: 2014-02-18
Binder学习总结_native(1)

这几天一直在看binder的结构,感叹这样天才的设计。
现在只研究到binder的native框架,在IPCThreadState以下,真正的driver和数据交换还需要进一步研究。在此记录一些目前的体会。

1.IInterface的作用
个人感觉,这个IInterface严格上讲,并不是Binder这个框架的一部分。
它的作用是提供了一个common的方式,可以将IBinder与Service进行显示的转换。
因为在进行IPC时,实际的service IXXXService要转换成IBinder,才能传递给ServiceManager进行注册检索,或者传递给Client进行调用。
而且Client拿到ServiceManager回传的IBinder以后,又要转换回IXXXService进行功能调用,所以IInterface产生了,提供了IXXXService与IBinder互相转换的功能。

(1)IXXXService转换IBinder实现:
IXXXService继承自IInterface,所以IInterface中的asBinder()方法,会将自身,也就是IXXXService转换成一个IBinder对象。
sp<IBinder> IInterface::asBinder()
{
    return this ? onAsBinder() : NULL;
}
这个onAsBinder()是一个虚拟方法,实际上是有IInterface的两个子类BpInterface和BnInterface实现的。
BpInterface的实现:
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
    return remote(); //调用它的父类BpRefBase的remote()方法,返回IBinder,其实就是一个BpBinder
}
BnInterface的实现:
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
    return this; //就是返回自身,因为BnInterface就是从BBinder继承的,BBinder又是继承自IBinder
}

(2)IBinder转换IXXXService实现:
当一个Client拿到ServiceManager返回的IBinder时,需要转换为IXXXService接口,才能调用它的功能。
这个转换,是由IInterface中定义的宏DECLARE_META_INTERFACE来声明的asInterface完成的,并由宏IMPLEMENT_META_INTERFACE实现的。
将宏代码IMPLEMENT_META_INTERFACE展开后得到:
android::sp<IXXXService> I##INTERFACE::asInterface(                
            const android::sp<android::IBinder>& obj)                   
{                                                                   
    android::sp<IXXXService> intr;                                 
    if (obj != NULL) {                                              
        intr = static_cast<IXXXService*>(                          
            obj->queryLocalInterface( //先调用queryLocalInterface,这个方法是IBinder定义的,默认实现是返回NULL,而在BBinder的子类BnInterface中,重载了该方法,返回this,而
                                      //BpInterface并没有重载,使用IBinder的默认实现,返回NULL。                             
                    IXXXService::descriptor).get());               
        if (intr == NULL)

Unknown macro: {                                                  intr = new BpXXXService(obj); //如果queryLocalInterface返回NULL,就构造一个BpXXXService返回,Client得到的正是这个BpXXXService        }

                                                           
    }                                                               
    return intr;                                                    
}
总结一下,如果传进来的obj参数,是一个BBinder,就返回自身(这种情况应该是service和client在同一进程),如果是一个BpBinder,就new一个代理对象返回(这种情况应该是service和client在不同进程)。                                   

2.IBinder, BBinder和BpBinder
这3个类,是对Android Binder框架的抽象,其实这个BBinder,改成BnBinder可能更形象一些。
但是要注意的是,一个IXXXService的继承图中,BpBinder并不在这个继承关系之中,也就是说BpBinder并没有子类。但是BBinder是在这个继承关系当中的,它的子类就是BnInterface。
换句话说,BBinder和BpBinder的功能并不是对称的,以前就是没有理解到这一点,才会一直很糊涂。

BpBinder的是存在于BpRefBase中的mRemote的成员变量中。从Client调用Service的过程中分析,就更清楚了。
假设有一个IXXXService接口:
class IXXXService : public IInterface {
    ....
    public void helloWorld(const char* str);
    ....
}
(1)client调用service
    client得到一个BpXXXService以后
    (a)会调用BpXXXService实现的helloWorld,它会将str参数打包到Parcel中。然后调用remote()->transact(xxx)
    (b)remote()是在BpXXXService的父类BpRefBase中实现的,返回的就是一个BpBinder.实际上调用的就是BpBinder的transact
    (c)BpBinder的transact实现,就是直接调用IPCThreadState::self()->transact()发送数据。
(2)service接收client请求:
    (a)通过IPCThreadState接收到client的请求后,首先会调用BBinder的transact方法。
    (b)BBinder的transact方法又会调用子类实现的虚拟方法onTransact。这个虚拟方法是在BnXXXService中实现的。
    (c)onTransact方法,会通过传递进来的参数来判断,需要调用IXXXService中的那个方法,示例中只有一个helloWorld方法。
    (d)直接调用helloWorld,就会找到它的真正实现,也就是BnXXXService的子类XXXService中的helloWorld方法。
总结一下,从上面的流程当中就可以看出前文说的,BpBinder并不在继承关系当中,它只是一个打包数据,并通过IPCThreadState::self()->transact()方法发送出去。
而BBinder和BnXXXService的作用,就是接收IPCThreadState传递过来的信息,解包数据,并调用XXXService真正的实现。

IPC的数据处理,Binder Driver和ServiceManager学习后会继续分析总结。



    
[3] wp7中关于ListPicker的ItemSource的一个疑义
    来源: 互联网  发布时间: 2014-02-18
wp7中关于ListPicker的ItemSource的一个疑问

今天意外的发现struct与class之间的一些区别。就是这些区别导致了在使用这两个类型的数据作为ListPicker的ItemSource时的效果不一样。

(1)使用struct类型对象作为ListPicker的ItemSource

首先定义了一个这样一个struct结构体:

    public struct MonthListPickerItem
    {
        public long Month;
        public bool IsLunarMonth;

        public MonthListPickerItem(long month, bool isLunarMonth)
        {
            Month = month;
            IsLunarMonth = isLunarMonth;
        }
    };

然后这样使用它:

    public partial class MonthListPicker : UserControl
    {
        #region Constants

        private int January = 1;
        private int December = 12;
        private int MonthsInYear = 12;

        #endregion

        #region Data Members

        private List<MonthListPickerItem> m_SelectedItems;
        
        #endregion

        #region Constructor

        public MonthListPicker()
        {
            InitializeComponent();

            m_SelectedItems = new List<MonthListPickerItem>();
            m_Era = Era.Solar;
        }

        #endregion

        #region Public Properties

        public List<MonthListPickerItem> SelectedItems
        {
            get
            {
                List<MonthListPickerItem> copy = new List<MonthListPickerItem>();
                copy.AddRange(m_SelectedItems);

                return copy;
            }
            set
            {
                if (!m_SelectedItems.Equals(value))
                {
                    m_SelectedItems.Clear();
                    m_SelectedItems.AddRange(value);
                }
            }
        }

        public Era Era
        {
            get
            {
                return (Era)m_Era;
            }
            set
            {
                if (m_Era != value)
                {
                    m_Era = value;                                                                                                                                            NotifyEraPropertyChanged(value);
                }
            }
        }

        #endregion

        #region Event Handlers

        private void InitMonthLP()
        {
            List<MonthListPickerItem> monthsOfYear = new List<MonthListPickerItem>();
            bool isLunarMonth = (Era == Era.Lunar);
            for (int i = January; i <= December; ++i)
            {
                monthsOfYear.Add(new MonthListPickerItem(i, isLunarMonth));
            }

            MonthLP.ItemsSource = monthsOfYear;            // 设置itemsource为12个月份
            MonthLP.SelectedItems = m_SelectedItems;       // 设置选中的月份
        }

        private void NotifyEraPropertyChanged(Era era)
        {
            // do something
        }

        #endregion
    }
这样的代码运行起来时没有问题的,ListPicker的SelectedItems会有选中效果。

(2)使用class类型对象作为ListPicker的ItemSource

但是当我将MonthListPickerItem改为class类型时,代码没有编译错误,但是在运行时设置SelectedItems没有效果,也就是没有item被选中。

例如:

    public class MonthListPickerItem
    {
        public long Month{get;set;}
        public bool IsLunarMonth{get;set;}

        public MonthListPickerItem(long month, bool isLunarMonth)
        {
            Month = month;
            IsLunarMonth = isLunarMonth;
        }
    };

这到底是什么原因呢?
struct对象是在栈上创建的,而class对象则是在堆上创建的。在堆上创建的对象在数据块索引和地址空间方面会不一样,即使存储的内容一样;程序在设置选中项的时候,估计是这些方面做了判断,只要是class类型对象使用了new,实际上它们就永远不相等,因此也就是找不到要默认选中的选项。

因此会出现这样的选中项设置无效的情况吧。

------------------------------------------------------------------

但目前没有深究这些问题,实际情况是不是上面所说的这样也不能保证,先作为一个笔记吧,有时间再来确定一下。




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