最近在看APK Expansion Files,遇到一个问题记录如下
问题现象:
调用
bindService(intent, mServiceConnectionImpl, this.BIND_DEBUG_UNBIND);
该方法返回值为true,但是未调用mServiceConnectionImpl中的方法:
public void onServiceConnected(ComponentName name, IBinder service){ }
解决办法:
调用
bindService(intent, mServiceConnectionImpl, this.BIND_AUTO_CREATE);
即可
目录:
前言
一.准备学习
二.针对性逐行研究代码
三.构建自己的应用流图,编写程序,调试通过
四、small tips
前言:学习背景:电子通信专业,相关专业课程都有学习,没学过python(大多数都没有学过)C++学习过,只学过C的话最好对面向对象编程的类,封装,重构有所了解,学习,有助于学习python编程。
一、 准备学习
步骤:入门中文文档——> 登陆gnuradio/wiki网站查看入门英文相关手册——>根据wiki在电脑上手动安装GNURadio平台(首先在电脑上安装虚拟机,虚拟机上安装LINUX系统)——>了解linux系统的基本操作指令,会运行安装好后的gnuradio源代码。
1.入门中文文档:
重点:[1]GNU_Radio入门_V0.99,黄琳著。
[2] Python简明教程
其他:对软件无线电基本概念,发展历史,随便找本书,有所了解。
2.http://gnuradio.org/redmine/projects/gnuradio/wiki,关于gnuradio的介绍这个网站是最全面的,入门时可以看看安装步骤介绍和FAQ。
3.安装最好参见上面网站的说明,因为其版本更新是最迅速的,中文文档版本过时,不便参考。
4.推荐论坛:http://www.ruby-forum.com/forum/gnuradio这个英文论坛确实有很多东西可以看,学会用搜索;http://gnuradio.cc/index.php?m-bbs.html这个中文论坛比较冷清,但是有牛人解答,尤其是meteor,很热心,很牛,几乎有问必答。
5.有问题时针对性在论坛和网站FAQ上都搜索不到时,可以直接google(英文学术搜索比百度好),或者直接联系牛人。(加群,邮件联系)
二、针对性逐行研究代码
根据课题要求,在下载的gnuradio包中查看相应源代码,找到主程序。
这里以我的OFDM举例,相关程序涉及一个只有数据发送的benchmark代码,一个ofdm收发的benchmark ofdm。
●理解程序第一步:重点理解python程序的流图机制,顶层文件都是python程序,底层C++写的信号处理模块可暂时不了解,可通过在GRC里查找相应模块了解其接口参数即可。先从简单程序入手,GNURadio入门文档的第四章在这一阶段要重新重点看。
另外,由于python编程的重要性,个人认为简明教程还是不太够,最好再看一本厚一点的编程入门。推荐清华大学出版的james payne的python编程入门经典,其他也行。
●Benchmark代码详细解析有gnuradio中文论坛版大meteor的解释非常详细,对读懂这个程序有很大帮助。因为gnuradio就是为了实现各种无线电应用,也就是一个收发通信系统,所以在阅读其他程序之前也非常有必要先把这个物理层的收发程序读懂。
●其他程序的阅读我认为大框架就是要搞懂流图的建立,一个大的应用一般自己编写了几个python文件,流图流向涉及好几个自己编写的文件,一个办法就是在该主程序顶头用from…import引入模块的句子中找到从当前路径引入的模块,再在当前路径中找到对应.py文件,联系起来即可知道流图去向。其他引入模块若为from gnuradioimport…则为从gnuradio中引入的模块,直接import则为调用的python的内嵌模块。
▲TIPS:
◆查找gnuradio的模块:为了读懂程序,不需要在阅读到前几句引入模块的时候就赶紧到gnuradio包中去搜索对应模块,而是读到具体语句的时候,确定是引用了gnuradio中模块的相关函数的时候再去查找其作用,一般格式举例:gr.sizeof_gr_complex 规律:所有gnuradio的模块调用前缀都是gr.后面有横杠表示类的私有函数。
查找方法:在gnuradio包下,例如gnuradio- 3.5.0文件夹下,选择“搜索”,注意键入关键字搜索方法:例如gr.sizeof_gr_complex就可以键入sizeof而不是全部键入,可断句键入搜索,一般我们要找的是CC文件和H文件,其他文件不用看。
◆查找python函数:程序中没有任何前后声明的一般为python的内嵌函数,举例: data =source_file.read(pkt_size - 2),这里source_file为前面定义的一个文件变量,python把其当做对象,read()函数没有任何说明,即可分析其为python内嵌函数。查找方法:安装一个python编辑调试器IDLE非常有必要!!!安装IDLE以后会有一个强大的帮助文档,类同matlab的帮助文档,可以直接在安装目录里打开,也可以打开编辑器以后按F1调出文档,要学会用其搜索功能,所有python函数都可以搜索到,对理解程序非常有帮助,另外,也可以尝试用编辑器编写一些小的python程序,帮助理解其编程原理。在GNURadio平台上构建自己的无线应用,初期阶段其已有C++编写的信号处理模块绝对已经足够,所以python编程就非常重要。也不需要单纯对python了解太深,脱离了gnuradio个人认为得不偿失。
三、构建自己的流图,编写程序,调试通过
●GRC的运用:初期学习构建简单通信系统可以尝试用grc,构建成功后仔细分析其生成的.py文件,对python程序的流图机制理解很有帮助。这一步甚至可以放在逐行阅读程序(第二步)之前。GRC的使用非常简单,不用细说,就是拖动模块过来连线,刚开始用的时候不知道怎么连线,有人告诉就是把两个端点各单击一次即可,若有问题则主要是原理的问题,对于模块接口参数的设计理解了原理根据提示修改一般没有问题,不过还是建议自己的程序不要用GRC,自己编写会好得多,参考模版也建议不要参考GRC生成的程序,参考源代码为好。
●在心中构建了一个流图以后,一个当然是可以用GRC仿真检验后再自己编程,如果GRC不能完成,则可以自己编程实现了。由于python是脚本语言,不需编译,所以目前作为仍然是新手级别,我只知道在终端直接运行,根据错误提示调试,新手遇到的问题多于缩进有关:indentation error:unexpected indent
或者变量定义位置:attribute error:”str” object has no attribute“read”(属性错误),这个错误在于我把变量写在了一个if语句下面,后面else又用了,总之都是基础错误,python语言对于变量不需要事先声明,所以对于新手理解程序有点障碍,必须慢慢习惯。再有莫名其妙的问题在各个论坛问了也没人理的时候就有可能是你的流图接口有问题了,这个必须就要自己慢慢的把自己用到的各个模块的接口搞懂然后再更改就行了。这个时候也可以求助于GRC看能不能解决。
四、small tips
1、USRP采样率(sample rate)问题:
USRPN系列时钟为100MSPS(samples persecond):可调范围为masterclock/4----masterclock/512范围,通过调节比特率(bitrate)和每符号样值率(samples per symbol),公式如下:
采样率=符号速率(symbol rate)*每符号样值数=时钟频率(masterclock)/2的n次幂(n属于2-9)
符号速率=比特率/每符号比特数
2.python中的数值类型和长度:重点:complex型。查找文档费了点时间,这里直接贴出吧,复数complex是按照(实部,虚部)存储的,实部,虚部都是按浮点型float存储的,python没有double型,与matlab接口时要注意,由于文档中说数据类型的长度与版本和机器都有关,所以建议在python编辑器IDLE上编写一个小程序测试一下,一般float是4个字节,所以complex就是8个字节。
Gnuradio编程就是python编程,所以其数据类型是相通的。
这里注意★python操作的数据对象(据我看的程序貌似都是)string,所以其函数一般都把得到的数据转成了string型,这里不用紧张,收发是匹配的,会有还原。典型函数如:chr();ord();
表视图继承自UIScrollView,这样的继承关系使得表视图可以实现上、下滚动。
UITableViewDatasource:实例化表视图时,必须采用该方法来实现数据源的配置
UITableViewDelegate:表视图的委托方法,一般用于处理表视图的基本样式以及捕捉选中单元格选中事件
表视图的结构:
表视图由头部、尾部视图,中间有一连串的单元格视图
表视图的头部由tableHeaderView属性设置,尾部视图通过tableFooterView属性设置
分组表格由一系列的section视图组成,每一个section又包含一个连续的单元格
每个section视图也由头部视图和尾部视图,通过委托方法代理
cell的使用:
首先定义一个标示符
其次,检查表视图中是否存在闲置的单元格,如果有取出来,没有则重新创建
第一、UITableViewDatasource 相关的方法
添加数据源的方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; // 获得section包含的cell个数
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.arrayList count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"the section is %d",indexPath.section); static NSString *idendifier=@"cellIdentify"; UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:idendifier]; if (!cell) { cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:idendifier]; } cell.textLabel.text=[self.arrayList objectAtIndex:indexPath.row]; return cell; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return @"andy"; } - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { return @"richard"; }
表视图的编辑、移动、删除等:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index; // tell table which section corresponds to section title/index (e.g. "B",1))
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
第二、UITableViewDelegate相关的方法
// Called before the user changes the selection. Return a new indexPath, or nil, to change the proposed selection.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPathNS_AVAILABLE_IOS(3_0);
// Called after the user changes the selection.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
sample:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { DetailViewController *detailVC=[[[DetailViewController alloc] init] autorelease]; [self.navigationController pushViewController:detailVC animated:YES]; NSLog(@"clicked"); }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
sampleCode:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row==1) { return 100; }else { return 50; } } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 50; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 60; }
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; // custom view for header. will be adjusted to default or specified header height
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
sample code:- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UIView *headerView=[[[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 40)] autorelease]; headerView.backgroundColor=[UIColor yellowColor]; UILabel *label=[[[UILabel alloc] initWithFrame:CGRectMake(20, 20, 300, 30)] autorelease]; label.text=@"header"; [headerView addSubview:label]; return headerView; } - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { UIView *headerView=[[[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 40)] autorelease]; headerView.backgroundColor=[UIColor redColor]; UILabel *label=[[[UILabel alloc] initWithFrame:CGRectMake(20, 20, 300, 30)] autorelease]; label.text=@"foot"; [headerView addSubview:label]; return headerView; }