当前位置:  编程技术>移动开发
本页文章导读:
    ▪canvas.drawBitmap()使图片全屏展示        canvas.drawBitmap()使图片全屏显示有时候我们这使用canvas.drawBitmap()时,需要使图片全屏显示,这个时候我们可以这样: Rectf rectF = new RectF(0, 0, w, h); //w和h分别是屏幕的宽和高,也就是你想让图.........
    ▪ 【Objective-c算法】 A*自动寻道算法        【Objective-c算法】 A*自动寻路算法 A*算法适合在静态环境中寻路,也就是说周围的物体不会动态的移动。 需要2个表,分别保存待检测和已检测的格子: @interface AStarFinder : NSObject { NSMutableAr.........
    ▪ 起动MixerThread       启动MixerThread今天想改变一下MixerThread的优先级。 看了下,原来在Thread的run函数中可以指定线程的优先级。 接下来就需要找到哪个地方调用了MixerThread的run函数,也就是启动了MixerThread。 想.........

[1]canvas.drawBitmap()使图片全屏展示
    来源: 互联网  发布时间: 2014-02-18
canvas.drawBitmap()使图片全屏显示

有时候我们这使用canvas.drawBitmap()时,需要使图片全屏显示,这个时候我们可以这样:

 


    
[2] 【Objective-c算法】 A*自动寻道算法
    来源: 互联网  发布时间: 2014-02-18
【Objective-c算法】 A*自动寻路算法

A*算法适合在静态环境中寻路,也就是说周围的物体不会动态的移动。

需要2个表,分别保存待检测和已检测的格子:

openTable保存的就是当前格子四周的格子(最多为8个),只保存满足条件的格子,不能是障碍物 或者出屏幕了。


你可以这样来初始化它们:

openTable = [[NSMutableArray alloc] initWithCapacity:map.mapSize.width*map.mapSize.height];
closeTable = [[NSMutableArray alloc] initWithCapacity:map.mapSize.width*map.mapSize.height];

看看A*算法的核心代码:



看看 bestTilePoint 函数:


总之 bestTilePoint函数就是用来找到最合适的移动方向。


看看 是如何处理每一个格子的:


DEMO下载


    
[3] 起动MixerThread
    来源: 互联网  发布时间: 2014-02-18
启动MixerThread
今天想改变一下MixerThread的优先级。
看了下,原来在Thread的run函数中可以指定线程的优先级。
接下来就需要找到哪个地方调用了MixerThread的run函数,也就是启动了MixerThread。


想到,调用AudioTrack的start函数,可以开始播放。MixerThread的启动是不是由这儿驱动的呢?


看了下函数AudioTrack::start,有两个地方可疑:
           t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
            status = mAudioTrack->start();


不过第一处指明了thread名称为AudioTrackThread,并非Mixer Thread。
既然看了,也就看看t是个嘛东东吧:
    sp<AudioTrackThread> t = mAudioTrackThread;
mAudioTrackThread在AudioTrack::set函数中被赋值:
        mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
AudioTrackThread::threadLoop函数的实现:
    return mReceiver.processAudioBuffer(this);
也就是调用了函数AudioTrack::processAudioBuffer。
看了看AudioTrack::processAudioBuffer函数的处理,感觉也就前面对callback的处理有用点。
比如,原来如果调用过SetMarkerPosition,而此时如果满足了条件,就会调用相应的回调函数。
后面的处理,没看明白什么意思,唯一的数据copy发生在16bit与8bit的转换。


那就看看mAudioTrack->start()吧。
函数AudioTrack::createTrack对mAudioTrack进行了赋值:
    mAudioTrack = track;

track的来历:
    sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
                                                      streamType,
                                                      sampleRate,
                                                      format,
                                                      channelCount,
                                                      frameCount,
                                                      ((uint16_t)flags) << 16,
                                                      sharedBuffer,
                                                      output,
                                                      &mSessionId,
                                                      &status);
 
函数AudioFlinger::createTrack返回的是一个TrackHandle对象:
        trackHandle = new TrackHandle(track);


函数AudioFlinger::TrackHandle::start的实现也不复杂:
    return mTrack->start();


mTrack就是刚才传入的track。
        track = thread->createTrack_l(client, streamType, sampleRate, format,
                channelCount, frameCount, sharedBuffer, lSessionId, &lStatus);


函数 AudioFlinger::PlaybackThread::createTrack_l返回的是一个Track对象:
        track = new Track(this, client, streamType, sampleRate, format,
                channelCount, frameCount, sharedBuffer, sessionId);


函数AudioFlinger::PlaybackThread::Track::start调用了函数AudioSystem::startOutput。
层层调用,最终调到了函数AudioPolicyManagerBase::startOutput。
不过,并没有看到有启动MixerThread的地方。


先小结一下。


创建AudioTrack对象的时候,会先根据stream type获取一个output。
获取的方法是调用函数AudioSystem::getOutput。
函数AudioSystem::getOutput中,会调用函数AudioSystem::get_audio_policy_service来获取AudioPolicyService。
AudioPolicyService对象若尚未被创建,函数AudioSystem::get_audio_policy_service会创建一个。
在AudioPolicyService的构造函数中调用了AudioPolicyManagerBase的构造函数。
AudioPolicyManagerBase的构造函数中打开了输出用的output。
打开方法是通过调用函数AudioPolicyService::openOutput最终调用到了函数AudioFlinger::openOutput。
函数AudioFlinger::openOutput中调用到了HAL层中的函数openOutputStream。
HAL层中通过调用ALSA Lib的接口,根据device name最终打开了output stream。


回到AudioPolicyManagerBase的构造函数中。
其中打开了output之后,为每个output创建了一个playback thread。
也就是说,底层的每个device对应了一个playback thread。


AudioTrack的构造函数获取到output之后,接下来调用函数AudioFlinger::createTrack来创建track。
track最终对应到了playback thread中的track。


调用函数AudioTrack::write往AudioTrack中写数据的时候,其实是写到了AudioTrack中的audio_track_cblk_t对象中。
调用函数AudioTrack::start最终调用到了函数AudioFlinger::PlaybackThread::Track::start,其中将track自己设置为有效,并将自己追加到对应的playback thread的track列表中。
MixerThread的threadloop函数中,会处理所有的active 的track,进行mix,并将数据写入到硬件。


还是回去看看Mixer Thread是怎么启动的吧。
搜了下,发现函数AudioFlinger::PlaybackThread::onFirstRef中有调用run。
PlaybackThread是MixerThread的父类。
估计MixerThread也就是在这儿启动的了。
查了下资料,onFirstRef是在创建第一个强连接是被创建,在创建对象的时候会被调用。


由前面所知,AudioPolicyManagerBase的构造函数中创建了playback thread,这里的playback thread其实是MixerThread。
打log验证了一下,果然,在AudioPolicyManagerBase的构造函数中引起了AudioFlinger::PlaybackThread::onFirstRef函数的调用,并最终启动了MixerThread。

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