当前位置:  编程技术>移动开发
本页文章导读:
    ▪Fedora14上自带jdk1.6版本 安装jdk1.7不识别的有关问题解决        Fedora14下自带jdk1.6版本 安装jdk1.7不识别的问题解决安装jdk1.7.0_04后,同时设置环境变量,并且source。可是java -version查看后,还是只能查看到jdk1.6和jdk1.5一共两个版本,这两个版本都是fedora自.........
    ▪ slab分配器 - 范例用法        slab分配器 - 实例用法slab分配器 - 实例用法     其原理此处不再赘述,请参看:http://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/ 1. 定义一个 kmem_cache 对象,然后对其进行初始化 static struct .........
    ▪ 短信发送流程-应用层       短信发送流程--应用层短信发送流程应用层解析 1、涉及的类 com.android.mms.ui.ComposeMessageActivity com.android.mms.data.WorkingMessage com.android.mms.transaction.MessageSender com.android.mms.transaction.SmsMessageSender com.a.........

[1]Fedora14上自带jdk1.6版本 安装jdk1.7不识别的有关问题解决
    来源: 互联网  发布时间: 2014-02-18
Fedora14下自带jdk1.6版本 安装jdk1.7不识别的问题解决

安装jdk1.7.0_04后,同时设置环境变量,并且source。可是java -version查看后,还是只能查看到jdk1.6和jdk1.5一共两个版本,这两个版本都是fedora自带的。

解决方法:

#:  alternatives --install /usr/bin/java java /usr/local/android/jdk1.7.0_04/bin/java 500 


注意;/usr/local/android/jdk1.7.0_04/ 是我的jdk安装路径。

然后:

alternatives --config java

会出现三个选项,选择你刚才安装的1.7的jdk就可以了。



    
[2] slab分配器 - 范例用法
    来源: 互联网  发布时间: 2014-02-18
slab分配器 - 实例用法

slab分配器 - 实例用法
    其原理此处不再赘述,请参看:http://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/
1. 定义一个 kmem_cache 对象,然后对其进行初始化

static struct kmem_cache *sample_cachep;
static void init_sample_cachep( void )
{
    sample_cachep = kmem_cache_create( 
       "sample_cachep", /* Name */
   32,   /* Object Size */
   0,   /* Alignment */
   SLAB_HWCACHE_ALIGN, /* Flags */
   NULL);   /* Constructor */
   return;
}

    这里是采用的通用slab缓存方式实现,这个特定的缓存包含 32 字节的对象,并且是硬件缓存对齐的(由标志参数 SLAB_HWCACHE_ALIGN 定义)。
    如果采用专用slab缓存,那么必须要知道建立缓存对象的大小,比如,我们需要为sample_struct结构体建立一个专用的slab缓存,那么其调用格式如下:

static struct kmem_cache *sample_struct_cachep;
static void init_sample_struct_cache( void )
{
    sample_struct_cachep = kmem_cache_create( 
       "sample_struct_cachep",  /* Name */
   sizeof(struct sample_struct), /* Object Size */
   0,     /* Alignment */
   SLAB_HWCACHE_ALIGN,  /* Flags */
   NULL);  /* Constructor */
   return;
}

接下来以专用slab缓存为实例
2. 使用所分配的 slab 缓存对象,或释放所分配的 slab 缓存对象

int slab_test( void )
{
       struct sample_struct *object;
       printk( "Cache name is %s/n", kmem_cache_name( sample_struct_cachep ) );
       printk( "Cache object size is %d/n", kmem_cache_size( sample_struct_cachep ) );
       object = kmem_cache_alloc(sample_struct_cachep, GFP_KERNEL);
       if (object) {
             kmem_cache_free(sample_struct_cachep, object);
       }
       return 0;
}

3. slab 缓存的销毁。调用者必须确保在执行销毁操作过程中,不要从缓存中分配对象。

static void remove_sample_struct_cache( void )
{
      if (sample_struct_cachep) 
             kmem_cache_destroy( sample_struct_cachep );
      return;
}

4.所在slab缓存使用过程中,可以通过slabtop查看。

5. 实例

 

/**********************************************
 * Author: lewiyon@hotmail.com
 * File name: slabmod.c
 * Description: slab缓存使用实例 
 * Date: 2012-07-26
 *********************************************/

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/module.h> 

#include <linux/unistd.h>
//#include <sys/type.h>
#include <linux/slab.h>

MODULE_LICENSE("GPL");  

#define first   1000     /* 第一次尝试分配1000个对象 */

struct sample_struct {
    int id;
    char name[20];
    char address[50];
};
static struct kmem_cache *sample_struct_cachep;
    
static struct sample_struct *sample1[first];

static int sample_mod_init(void)
{
    int i;

    sample_struct_cachep = kmem_cache_create(
            "sample_struct_cachep",         /* Name */
            sizeof(struct sample_struct),   /* Object Size */
            0,                              /* Alignment */
            SLAB_HWCACHE_ALIGN,             /* Flags */
            NULL);                          /* Constructor */
    /* 确保创建成功:有可能失败 */
    if (NULL == sample_struct_cachep)
        return 1;
    printk(KERN_INFO "Cache name is %s\n", 
            kmem_cache_name(sample_struct_cachep));
   
    /* 首次分配 */
    for (i = 0; i < first; i++)
    {
        sample1[i] = kmem_cache_alloc(sample_struct_cachep, GFP_KERNEL);
        if (NULL == sample1[i])
        {
            int ii;
            printk("First alloc ERR: %d/n", i);
            for (ii = 0; ii < i; ii++)
            {
                kmem_cache_free(sample_struct_cachep, sample1[ii]);
                sample1[ii] = NULL;
            }

        }
    }

    return 0;
}


static void sample_mod_exit(void)
{
    int i;

    if (sample1[0])
    {
        for (i = 0; i < first; i++)
            {
                kmem_cache_free(sample_struct_cachep, sample1[i]);
                sample1[i] = NULL;
            }
    }

    if (sample_struct_cachep) 
    {
        kmem_cache_destroy( sample_struct_cachep );
        printk(KERN_INFO "Destroy sample_struct_cachep!\n");
    }

    return ;
} 

module_init(sample_mod_init); 
module_exit(sample_mod_exit);

MODULE_AUTHOR("lewiyon@hotmail.com"); 
MODULE_DESCRIPTION("A Simple slab sample"); 

插入模块、删除模块前后slabtop观察结果

[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1020 100%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1010  99%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1002  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1001  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1000  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1000  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1000  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1000  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
  1020   1000  98%    0.12K     34       30       136K sample_struct_cachep
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
[root@RedHat ~]# slabtop -o | egrep "OBJS|sample_struct_cachep"
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
[root@RedHat ~]#
分析:

a. 再没有插入模块时,没有数据

b. 插入模块时,新建slab,这是数据都是active的,此时对象数目为OBJS = SLABS * OBJ/SLAB = 34*30 = 1020;

c. 随着模块稳定下来, 未使用的对象变为inactive,那么active数目就变味了1000;(与程序相对应)

d. 删除模块后,数据消失


    
[3] 短信发送流程-应用层
    来源: 互联网  发布时间: 2014-02-18
短信发送流程--应用层
短信发送流程应用层解析
1、涉及的类

com.android.mms.ui.ComposeMessageActivity
com.android.mms.data.WorkingMessage
com.android.mms.transaction.MessageSender
com.android.mms.transaction.SmsMessageSender
com.android.mms.transaction.SmsSingleRecipientSender
com.android.mms.transaction.SmsReceiverService
com.android.mms.transaction.SmsReceiver
2、时序图
说明:从ui界面开始,到调用中间层SmsManger的方法发送短信,大致时序就是这样,参考代码是android 2.3

3、流程解析 3.1 ComposeMessageActivity工作

该类是我们编辑短信的UI,与用户交互,如下图所示


当用户编辑完成,即可点击发送的按钮,将短信内容发送出去,点击sendbutton就会触发该button对应的监听器,由于ComposeMessageActivity实现了OnClickListener接口,所以最终调用到了onclick方法里。

1)onClick分析

   该方法做了两件件事情:

    一是调用isPreparedForSending方法判断当前短信是否准备发送,依据就是短信短信的接收者是否超过允许的上限,是否有接收者,以及短信是否有内容或者附件、主题之类的,不允许用户发送一条什么都没有的短信出去。

   二是,上面的检查通过调用confirmSendMessageIfNeeded方法开始发送流程。当然并不是调用了该方法就一定能发送成功,该方法同样会做一系列的检查,直到符合要求了才会放行。

2)confirmSendMessageIfNeeded分析 

该方法的逻辑调用如下图所示:

3)sendMessage方法分析
上图可以看出最后都要走到sendMessage来,我们来看看这个方法到底做了哪些工作。
通过查看代码我们可以发现最最核心的工作就是: 把发送短信的工作交给WorkingMessage,mWorkingMessage.send(mDebugRecipients);其他的工作也仅仅是做一些辅助型的操作。
小结:到此为止发送短信的工作交给了WorkingMessage,那ComposeMessageActivity主要的工作即是对双卡的处理。
3.2 WorkingMessage简单分析 1)send()分析
该方法做了五项工作:
一是  检查接收者列表时否为空,这里我就不做具体的分析。
二是将短信内容从8字节转换成7字节;
三是判断当前是否是发送彩信,我们当前是短信发送,所以可定不会走彩信的发送流程。
四是,将短信的签名加到短信的内容上。
五是调用preSendSmsWorker()方法。
2)preSendSmsWorker分析
一是重置界面,将界面上的各个组件全部清除
二是调用sendSmsWorker方法
三是删除草稿。
3)sendSmsWorker()所做的工作
调用SmsMessageSender的sendMessage()方法
3.3 SmsMessageSender简析
1)sendMessage()

该方法会调用queueMessage()方法把处理发送的任务抛出去。

2)queueMessage()
它的职责有两个:
一是将要发送的短息保存到数据库;
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
        boolean requestDeliveryReport = prefs.getBoolean(
                MessagingPreferenceActivity.SMS_DELIVERY_REPORT_MODE,
                DEFAULT_DELIVERY_REPORT_MODE);

        for (int i = 0; i < mNumberOfDests; i++) {
            try {
                log("updating Database with sub = " + mSubscription);
                Sms.addMessageToUri(mContext.getContentResolver(),
                        Uri.parse("content://sms/queued"), mDests[i],
                        mMessageText, null, mTimestamp,
                        true /* read */,
                        requestDeliveryReport,
                        mThreadId, mSubscription);
            } catch (SQLiteException e) {
                SqliteWrapper.checkSQLiteException(mContext, e);
            }
        }
二是,将任务转交到其他人,只不过它采用的方式是发广播;
     // Notify the SmsReceiverService to send the message out
        Intent intent = new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, null, mContext, SmsReceiver.class);
		intent.putExtra(SUBSCRIPTION, mSubscription);
        mContext.sendBroadcast(intent);
小结:该类做了一个很重要的工作就是讲要发送的短信保存进入数据库,然后发广播通知SmsReceiver;
3.4 SmsReceiver 到 SmsReceiverService 简析 实际上SmsReceiver这家伙也不是干事的人,它仅仅是拿到手里后马上就转交给SmsReceiverService服务了,“这事不归我管,我就是一个送快递的“,SmsReceiver的角色就是这样的,调用的方法可以参考时序图;
3.5 SmsReceiverService 简析 讲了很久终于干活的来了,它既然是一个服务,当然它会走自己的声明周期函数,首先是onCrate,该方法近几年是初始化,然后是onStartCommand(),该方法也没做啥,仅仅是向ServiceHandler发送消息,看来人家做苦力都做出心得了。
1)ServiceHandler处理发送请求
  @Override
        public void handleMessage(Message msg) {
            int serviceId = msg.arg1;
            Intent intent = (Intent)msg.obj;
            if (intent != null) {
                String action = intent.getAction();

                int error = intent.getIntExtra("errorCode", 0);
              if (SMS_RECEIVED_ACTION.equals(action)) {
                    handleSmsReceived(intent, error);
                } else if (SMS_CB_RECEIVED_ACTION.equals(action)) {
                    handleCbSmsReceived(intent, error);
                } else if (ACTION_BOOT_COMPLETED.equals(action)) {
                    handleBootCompleted();
                } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
                    handleServiceStateChanged(intent);
                } else if (ACTION_SEND_MESSAGE.endsWith(action)) {
                    handleSendMessage(intent);
                }
            }
            // NOTE: We MUST not call stopSelf() directly, since we need to
            // make sure the wake lock acquired by AlertReceiver is released.
            SmsReceiver.finishStartingService(SmsReceiverService.this, serviceId);
        }
    }
这里接收到发送后会走handleSendMessage方法;
2)handleSendMessage()简析:
1、判断双卡是否都可以使用,如果是获取当前的卡并调用sendFirstQueuedMessage(int sub)
2、如果双卡不是都可以使用,就直接调用sendFirstQueuedMessage()方法;
注意:这里是调用的两个不同的方法,看他们的参数你就知道了,但实际上sendFirstQueuedMessage()无参的函数最终还是通过调用sendFirstQueuedMessage(int sub)来实现的;相当于最后还是调用的sendFirstQueuedMessage(int sub)这个方法;
3)sendFirstQueuedMessage(int sub)简析
  它首先是从数据库中取出短信,然后调用SmsSingleRecipientSender的sendMessage()方法发送;
小结:大家可以发现走了半天,最后还是没有开始发送。
3.6  SmsSingleRecipientSender简析 sendMessage()说明:
一是对短信的内容进行分割
二是将短信保存到OUTBOX的数据库表里
三是将分割的短信分开发送
四是调用的SMSManger类的sendMultipartTextMessage()发送,将发送的具体操作转移给中间层。
具体代码如下:
if (mMessageText == null) {
            // Don't try to send an empty message, and destination should be just
            // one.
            throw new MmsException("Null message body or have multiple destinations.");
        }
        SmsManager smsManager = SmsManager.getDefault();
        ArrayList<String> messages = null;
        if ((MmsConfig.getEmailGateway() != null) &&
                (Mms.isEmailAddress(mDest) || MessageUtils.isAlias(mDest))) {
            String msgText;
            msgText = mDest + " " + mMessageText;
            mDest = MmsConfig.getEmailGateway();
            messages = smsManager.divideMessage(msgText);
        } else {
           messages = smsManager.divideMessage(mMessageText);
           // remove spaces from destination number (e.g. "801 555 1212" -> "8015551212")
           mDest = mDest.replaceAll(" ", "");
        }
        int messageCount = messages.size();

        if (messageCount == 0) {
            // Don't try to send an empty message.
            throw new MmsException("SmsMessageSender.sendMessage: divideMessage returned " +
                    "empty messages. Original message is \"" + mMessageText + "\"");
        }

        boolean moved = Sms.moveMessageToFolder(mContext, mUri, Sms.MESSAGE_TYPE_OUTBOX, 0);
        if (!moved) {
            throw new MmsException("SmsMessageSender.sendMessage: couldn't move message " +
                    "to outbox: " + mUri);
        }

        ArrayList<PendingIntent> deliveryIntents =  new ArrayList<PendingIntent>(messageCount);
        ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(messageCount);
        for (int i = 0; i < messageCount; i++) {
            if (mRequestDeliveryReport) {
                // TODO: Fix: It should not be necessary to
                // specify the class in this intent.  Doing that
                // unnecessarily limits customizability.
                deliveryIntents.add(PendingIntent.getBroadcast(
                        mContext, 0,
                        new Intent(
                                MessageStatusReceiver.MESSAGE_STATUS_RECEIVED_ACTION,
                                mUri,
                                mContext,
                                MessageStatusReceiver.class),
                        0));
            }
            Intent intent  = new Intent(SmsReceiverService.MESSAGE_SENT_ACTION,
                    mUri,
                    mContext,
                    SmsReceiver.class);

            int requestCode = 0;
            if (i == messageCount -1) {
                // Changing the requestCode so that a different pending intent
                // is created for the last fragment with
                // EXTRA_MESSAGE_SENT_SEND_NEXT set to true.
                requestCode = 1;
                intent.putExtra(SmsReceiverService.EXTRA_MESSAGE_SENT_SEND_NEXT, true);
                intent.putExtra(SUBSCRIPTION, mSubscription);
            }
            sentIntents.add(PendingIntent.getBroadcast(mContext, requestCode, intent, 0));
        }
        try {
            smsManager.sendMultipartTextMessage(mDest, mServiceCenter, messages, sentIntents,
                       deliveryIntents, mSubscription);
        } catch (Exception ex) {
            throw new MmsException("SmsMessageSender.sendMessage: caught " + ex +
                    " from SmsManager.sendTextMessage()");
        }
        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
            log("sendMessage: address=" + mDest + ", threadId=" + mThreadId +
                    ", uri=" + mUri + ", msgs.count=" + messageCount);
        }

4、总结

 这部分主要是分析了短息的发送的一个流程,从ui点击button开始到中间层执行发送的操作,当然这里还有很多不详的地方,我也在尝试不断的完善。




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