2014年6月16日星期一

AndroidParcelable

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
AndroidParcelable  阅读原文»

Android中的Parcelable接口

Android中的android.os.Parcelable接口用于替代Java序列化Serializable接口,Fragment以及Activtity之间都需要传递数据,有时甚至包含结构非常复杂的对象,这就需要先将这个对象序列化成二进制流,然后再进行传递了。

比如Fragment1向Fragment2传递数据,下面是Fragment1中创建Fragment2并传送数据的方法:

  Fragment2 fragment = new Fragment2();  Bundle bundle = new Bundle();  bundle.putParcelable("name", name);  fragment2.setArguments(bundle);  FragmentManager fm = getFragmentManager();  FragmentTransaction ft = getFragmentManager().beginTransaction();  ft.replace(R.id.container, fragment2)              .addToBackStack(null)              .commit();  

在Fragment2中,直接得到这个Parcelable对象即可:

  ParcelableName name = getArguments().getParcelable("name");  

不过,既然Java已经有了Serializable,那还需要Parcelable干什么呢?而且Serializable接口使用起来也非常简洁。

原因有三个,第一是效率,第二是效率,第三还是效率:

  1. Serializable用了很多反射,细心的人都知道,反射比正常的调用要慢100多倍

  2. Serializable会创建很多临时对象,这些临时对象会导致很多次垃圾回收,影响效率

有细心的人士做过测试,基本上Parcelable要比Serializable快上10-20倍。下面这个图是比较结构,更详细信息可以参考Parcelable vs Serializable

下面是android.os.Parcelable接口的定义,相比java.io.Serializable要复杂很多,不过,为了效率,你也只能忍了。

  public interface Parcelable {      public static final int PARCELABLE_WRITE_RETURN_VALUE = 0x0001;      public static final int CONTENTS_FILE_DESCRIPTOR = 0x0001;      public int describeContents();      public void writeToParcel(Parcel dest, int flags);      public interface Creator<T> {          public T createFromParcel(Parcel source);          public T[] newArray(int size);      }      public interface ClassLoaderCreator<T> extends Creator<T> {          public T createFromParcel(Parcel source, ClassLoader loader);      }  }  

看起来你至少需要实现两个方法describeContents()和writeToParcel():

  1. 第一个方法返回数字,一般返回0就好,只有FileDescriptor有特殊,上面的常量有定义。至于这有什么用,我也没有找到相关的信息,如果有读者理解,请留言告知我。

  2. 第二个方法用于将对象写入到Parcel对象中。详见下面的例子。

接着自己来实现一个包含了姓和名两个String字段的对象,如下:

      import android.os.Parcel;      import android.os.Parcelable;      public class ParcelableName implements Parcelable {          private String mSurname;          private String mGivenName;          public ParcelableName(String surname, String givenName) {              mSurname = surname;              mGivenName = givenName;          }          // 私有方法,因为我们不应该将参数是Parcel的构造函数暴露出去          private ParcelableName(Parcel source) {              this(source.readString(), source.readString());          }          @Override          public int describeContents() {              return 0;          }          public String getSurname() {              return mSurname;          }          public String getGivenName() {              return mGivenName;          }          @Override          public void writeToParcel(Parcel dest, int flags) {              dest.writeString(mSurname);              dest.writeString(mGivenName);          }          // 通过这个接口来创建Parcel对象,调用了私有的构造函数          public static final Parcelable.Creator<ParcelableName> CREATOR              = new Creator<ParcelableName>() {              @Override              public ParcelableName createFromParcel(Parcel source) {                  return new ParcelableName(source);              }              @Override              public ParcelableName[] newArray(int size) {                  return new ParcelableName[0];              }          };      }  

这里使用了Parcel.writeString()方法来将一个对象写入到序列化对象中,使用了Parcel.readString()从序列化对象中读取数据,一定要注意的是这里的写入和读取是有顺序的:先写的要先读。

注意,这里我们创建了一个私有的构造函数,这个构造函数的参数是Parcel对象,我们还创建了一个CREATOR的类变量,这个对象专门用于从序列化对象中创建ParcelableName对象,这是为了尽可能向外界隐藏序列化对象的实现细节,这种方式需要仔细琢磨,才能有所领悟。
值得提一下的是,Parcelable接口中还有一个ClassLoaderCreator接口,里面的createFromParcel()的第二个参数是一个ClassLoader对象,意味着我们可以反序列化不同的ClassLoader中的对象。

获取这段代码可以到:https://gist.github.com/zhlwish/3e2bbe9a15edf3b84ef7

这种代码写起来的确是挺麻烦的,有一个开源项目Parceler通过Anotation+代码生成的方法可以简化定义Parcelable对象的过程:

      @Parcel      public class Example {          String mSurname;          String mGivenName;          public Example(){ }          public Example(String surname, String givenName) {              mSurname = surname;              mGivenName = givenName;          }          public String getSurname() { return mSurname; }          public String getGivenName() { return mGivenName; }      }  

看起来简单多了,不过话说回来,如果你需要序列化的对象比较小,而且次数不多,不影响效率,你还是可以继续使用Serializable接口的,毕竟编码和维护的代价都小得多。

本文出自 "深入浅出Android" 博客,请务必保留此出处http://androidigging.blog.51cto.com/2753843/1426767

rhel7°  阅读原文»

浅谈测试rhel7新功能时的感受及遇到的问题

半夜起来看世界杯,没啥激情,但是又怕错误意大利和英格兰的比赛,就看了rhel7

相关新功能的介绍。

安装还算顺利,安装的界面比以前简洁的多,很清爽,分类很是明确。

有些奇怪的是,我安装的时候,怕有些基础的包没有装上去,所以选定了mini和Web的类型,结果还是有些基础的包没有安装,比如 ifconfig 。

虚拟机的网卡,被识别为ens,有意思。

wKioL1Oc-DfAOgXdAALmMK4uqD8902.jpg

  yum groupinstall Base  

这样的话,就可以把一些基础的包打上。可以正常的时候ifconfig lsof 。

这里需要说明的是,redhat7的测试的repo源貌似不能用,我跟着地址看了下。压根就没有,我想应该还是测试版的原因吧。 直接mount /dev/cdrom /mnt用的。

  [rhel-iso]  name=Red Hat Enterprise Linux 7  baseurl=file:///mnt/  enabled=1  

原文:http://rfyiamcool.blog.51cto.com/1030776/1426550

系统的分区默认是xfs格式,当然你还是可以用ext3,ext4的

  [root@localhost ~]# df -T  文件系统              类型     1K-blocks    已用     可用 已用% 挂载点  /dev/mapper/rhel-root xfs       39262208 3591304 35670904   10% /  devtmpfs              devtmpfs    500772       0   500772    0% /dev  tmpfs                 tmpfs       507508       0   507508    0% /dev/shm  tmpfs                 tmpfs       507508    2604   504904    1% /run  tmpfs                 tmpfs       507508       0   507508    0% /sys/fs/cgroup  /dev/sda1             xfs         494940   95444   399496   20% /boot  

发现rhel7的开发软件版本不低。

python 是2.7.5的了,和ubuntu一样。 java默认也给你装上了。perl在centos6应该是5.10的 ,现在更新到了5.16.3 。 至于为什么更新到perl6,估计和python3一样吧。

  [root@localhost ~]#  [root@localhost ~]#  [root@localhost ~]# python -V  Python 2.7.5  [root@localhost ~]# java -version  java version "1.7.0_45"  OpenJDK Runtime Environment (rhel-2.4.3.4.el7-x86_64 u45-b15)  OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)  [root@localhost ~]#  [root@localhost ~]#  [root@localhost ~]# perl -v  This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi  (with 24 registered patches, see perl -V for more detail)  

想安装pip但是iso没有python-pip这个包。rhel7的官方源又打不开,郁闷。本来打算用epel6试试,用不了,到epel官网一瞅。epel居然已经有对于rhel7的源了。

wKioL1Oc_I-DNIvwAAJX0WW4Glk978.jpg

原文:http://rfyiamcool.blog.51cto.com/1030776/1426550

简单测试下rhel7的openlmi,什么是openlmi,我看了下一些文档,他是一个类似func、但又不属于puppet这类的集群接口工具。

安装 yum install openlmi

安装 yum -y install openlmi-scripts*

scp root@10.10.10.71:/etc/Pegasus/client.pem /etc/pki/ca-trust/source/anchors/managed-machine-cert.pem

  [root@localhost ~]# lmi -h 10.10.10.71  lmi> hwinfo  username: pegasus  password:  error   : Failed to make a connection to "10.10.10.71": (0, 'Socket error: [Errno 113] No route to host')  error   : No successful connection made.  lmi>  lmi>  lmi>  

原因不详,我看了下官网对于openlmi的一些介绍,使用方面也是相当的简练。

  lmi -h ${hostname}  lmi> help  ...  lmi> sw search django  ...  lmi> sw install python-django  ...  lmi> exit  

rhel7 用systemd替换了咱们熟悉的sysv ,说是这东西很强大,说实话,资料还是少,这里就简单讲解下systemd的用法。

  # CentOS 6.4  service httpd (start|stop)  # rhel7  systemctl (start|stop) httpd.service  # CentOS 6.4  chkconfig httpd (on|off)  # rhel7  systemctl (enable|disable) httpd.service  $ cat /usr/lib/systemd/system/httpd.service    Description=The Apache HTTP Server  After=network.target remote-fs.target nss-lookup.target  [Service]  Type=notify  EnvironmentFile=/etc/sysconfig/httpd  ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND  ExecReload=/usr/sbin/httpd $OPTIONS -k graceful  ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop  # We want systemd to give httpd some time to finish gracefully, but still want  # it to kill httpd after TimeoutStopSec if something went wrong during the  # graceful stop. Normally, Systemd sends SIGTERM signal right after the  # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give  # httpd time to finish.  KillSignal=SIGCONT  PrivateTmp=true    WantedBy=multi-user.target  

会发现其实,用systemd参数更加的清晰,在sysv下,启动start、关闭stop、重启restart都是用$1来传递参数,但是在systemctl下,更直白点。很是像supervisord这个daemon程序。

  [root@localhost ~]# chkconfig --list|grep samba  注意:该输出结果只显示 SysV 服务,并不包含原生 systemd 服务。SysV 配置数据可能被原生 systemd 配置覆盖。        如果您想列出 systemd 服务,请执行 'systemctl list-unit-files'。        欲查看对特定 target 启用的服务请执行        'systemctl list-dependencies [target]'。  [root@localhost ~]#  [root@localhost ~]#  [root@localhost ~]# systemctl list-dependencies samba  samba.service  [root@localhost ~]#  

数据库方面真的是转向到mariadb,当我去安装mysql的时候,他会直接去安装mariadb ,看来mariadb大势所趋呀。

  [root@localhost ~]# 原文:http://rfyiamcool.blog.51cto.com/1030776/1426550  [root@localhost ~]# yum -y install mysql  已加载插件:langpacks, product-id, subscription-manager  This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.  file:///mnt/repodata/repomd.xml: [Errno 14] curl#37 - "Couldn't open file /mnt/repodata/repomd.xml"  正在尝试其它镜像。  软件包 1:mariadb-5.5.33a-3.el7.x86_64 已安装并且是最新版本  无须任何处理  [root@localhost ~]#  [root@localhost ~]#  [root@localhost ~]# yum -y install mysql-server  已加载插件:langpacks, product-id, subscription-manager  This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.  file:///mnt/repodata/repomd.xml: [Errno 14] curl#37 - "Couldn't open file /mnt/repodata/repomd.xml"  正在尝试其它镜像。  正在解决依赖关系  --> 正在检查事务  ---> 软件包 mariadb-galera-server.x86_64.1.5.5.37-2.el7 将被 安装  --> 正在处理依赖关系 mariadb-galera-common(x86-64) = 1:5.5.37-2.el7,它被软件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要  --> 正在处理依赖关系 galera >= 25.3.3,它被软件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要  --> 正在处理依赖关系 perl-DBI,它被软件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要  --> 正在处理依赖关系 perl-DBD-MySQL,它被软件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要  --> 正在处理依赖关系 perl(DBI),它被软件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要  --> 正在检查事务  ---> 软件包 galera.x86_64.0.25.3.5-5.el7 将被 安装  --> 正在处理依赖关系 nmap-ncat,它被软件包 galera-25.3.5-5.el7.x86_64 需要  ---> 软件包 mariadb-galera-common.x86_64.1.5.5.37-2.el7 将被 安装  ---> 软件包 perl-DBD-MySQL.x86_64.0.4.023-2.el7 将被 安装  ---> 软件包 perl-DBI.x86_64.0.1.627-1.el7 将被 安装  --> 正在处理依赖关系 perl(RPC::PlClient) >= 0.2000,它被软件包 perl-DBI-1.627-1.el7.x86_64 需要  --> 正在处理依赖关系 perl(RPC::PlServer) >= 0.2001,它被软件包 perl-DBI-1.627-1.el7.x86_64 需要  --> 正在检查事务  ---> 软件包 nmap-ncat.x86_64.2.6.40-2.el7 将被 安装  ---> 软件包 perl-PlRPC.noarch.0.0.2020-12.el7 将被 安装  --> 正在处理依赖关系 perl(Net::Daemon) >= 0.13,它被软件包 perl-PlRPC-0.2020-12.el7.noarch 需要  --> 正在处理依赖关系 perl(Net::Daemon::Log),它被软件包 perl-PlRPC-0.2020-12.el7.noarch 需要  --> 正在处理依赖关系 perl(Net::Daemon::Test),它被软件包 perl-PlRPC-0.2020-12.el7.noarch 需要  --> 正在检查事务  ---> 软件包 perl-Net-Daemon.noarch.0.0.48-4.el7 将被 安装  --> 解决依赖关系完成  依赖关系解决  ======================================================================================================================================   Package                                 架构                     版本                               源            

阅读更多内容

没有评论:

发表评论