首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

Android 插件开发--类加载器

1). Android中类加载器 Android 中常用的类加载器有DexClassLoader和PathClassLoader,其中PathClassLoader是Android应用中的默认加载器。 DexClassLoader可以加载任何路径下的apk/dex/jar/zip PathClassLoader只能加载/data/app中的apk,也就是已经安装在手机中的apk。 2). DexClassLoader 构造方法: public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) ; 其中: 继承自BaseDexClassLoader dexPath: 加载apk/dex/jar/zip的路径 optimizedDirectory: 是dex的输出路径 librarySearchPath: 加载时候需要用到的lib库,一般不用 parent: DexClassLoader指定的父加载器 3). PathClassLoader 构造方法: public PathClassLoader(String dexPath, ClassLoader parent); public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent); 其中 继承自BaseDexClassLoader dexPath: 加载dex路径 librarySearchPath: 加载时候需要用到的lib库 parent: PathClassLoader指定的父加载器 dex释放路径: /data/dalvik-cache 4). 查看各种类加载器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); printMoreClassLoader(); } private static final String TAG = "MainActivity"; /** * 打印各种类加载器 */ private void printMoreClassLoader() { Log.d(TAG, "Context类的类加载器:" + Context.class.getClassLoader()); Log.d(TAG, "ListView类的类加载器:" + ListView.class.getClassLoader()); Log.d(TAG, "应用程序默认的类加载器:" + getClassLoader()); Log.d(TAG, "系统类加载器:" + ClassLoader.getSystemClassLoader()); Log.d(TAG, "系统类加载器和Context类的类加载器是否相等:" + (Context.class.getClassLoader() ==ClassLoader.getSystemClassLoader())); Log.d(TAG, "系统类加载器和应用程序默认加载器是否相等:" + (getClassLoader() == ClassLoader.getSystemClassLoader())); Log.d(TAG, "================================================"); Log.d(TAG, "打印应用程序默认加载器的委派机制:"); ClassLoader classLoader = getClassLoader(); while (null != classLoader) { Log.d(TAG, "类加载器: " + classLoader); classLoader = classLoader.getParent(); } Log.d(TAG, "================================================"); Log.d(TAG, "打印系统加载器的委派机制:"); classLoader = ClassLoader.getSystemClassLoader(); while (null != classLoader) { Log.d(TAG, "类加载器:" + classLoader); classLoader = classLoader.getParent(); } } 打印结果: Context类的类加载器:java.lang.BootClassLoader@8b6e11e ListView类的类加载器:java.lang.BootClassLoader@8b6e11e 应用程序默认的类加载器:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.mazaiting.dynamicjar-2/base.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.mazaiting.dynamicjar-2/lib/arm64, /system/lib64, /vendor/lib64]]] 系统类加载器:dalvik.system.PathClassLoader[DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /vendor/lib64, /system/lib64, /vendor/lib64]]] 系统类加载器和Context类的类加载器是否相等:false 系统类加载器和应用程序默认加载器是否相等:false ================================================ 打印应用程序默认加载器的委派机制: 类加载器: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.mazaiting.dynamicjar-2/base.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.mazaiting.dynamicjar-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.mazaiting.dynamicjar-2/lib/arm64, /system/lib64, /vendor/lib64]]] 类加载器: java.lang.BootClassLoader@8b6e11e ================================================ 打印系统加载器的委派机制: 类加载器:dalvik.system.PathClassLoader[DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib64, /vendor/lib64, /system/lib64, /vendor/lib64]]] 类加载器:java.lang.BootClassLoader@8b6e11e

优秀的个人博客,低调大师

Docker社区版中Kubernetes开发

Docker社区版从17.12版本开始已经提供了对Kubernetes的支持。但是由于其安装过程依赖的镜像服务在国内访问很不稳定,很多朋友都无法配置成功。我们提供了一个简单的工具帮助大家开启Docker社区版的Kubernetes功能 开启 Kubernetes 从Docker官方站点下载并安装Docker for Mac或Docker for Windows 在 Docker -> Preferences ... 中,配置 registry mirror 为 https://registry.docker-cn.com 运行下列脚本可以从阿里云镜像服务下载Kubernetes安装所需Docker镜像,您也可以通过修改 images.properties 文件定义自己安装所需的Docker镜像 git clone https://gi

优秀的个人博客,低调大师

开发篇(Development)

目录 2. 软件工程 (Software Engineering) 2.1. Open Source and License 3. Trac 项目管理 3.1. Administration 3.1.1. General 3.1.2. Ticket System 3.1.3. Version Control 3.2. Wiki 3.3. Timeline 3.4. Roadmap 3.5. Ticket 4. Project directory 5. 版本控制及如何运作 5.1. 版本库布局 5.2. 策略 5.3. nightly version 5.4. rc1,rc2,rc4 5.5. 怎样写注释信息 5.5.1. Fixed Bug 5.5.2. Implemented 5.5.3. Add 6. 任务分配原则 7. 项目运作 8. 收集需求 9. 代码审查制度 9.1. Coding workflow 10. Release Notes 11. 版本发行 12. 每周例会 13. 编码风格 13.1. php 文件 13.1.1. 格式与 编码 13.1.2. 循环嵌套 13.1.3. 取出行尾的空格以及多余的换行符 13.1.4. php 标签 13.1.5. 头部注释 13.2. String 13.3. Database 13.3.1. 结果集使用注意事项 13.3.2. 索引 13.3.3. 缓存 Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a>comments powered by Disqus 原文出处:Netkiller 系列 手札 本文作者:陈景峯 转载请与作者联系,同时请务必标明文章原始出处和作者信息及本声明。

优秀的个人博客,低调大师

Android应用开发—Intent组件详解

转载自:Android中Intent组件详解 Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件。 Intent本身是定义为一个类别(Class),一个Intent对象表达一个目的(Goal)或期望(Expectation),叙述其所期望的服务或动作、与动作有关的数据等。Android则根据此Intent对象之叙述,负责配对,找出相配的组件,然后将 Intent对象传递给所找到的组件,Android的媒婆任务就完成了。 在Google Doc中是这样描述Intent的(摘自Android中文翻译组) 当接收到ContentResolver发出的请求后,内容提供者被激活。而其它三种组件──activity、服务和广播接收器被一种叫做intent的异步消息所激活。intent是一个保存着消息内容的Intent对象。对于activity和服务来说,它指明了请求的操作名称以及作为操作对象的数据的URI和其它一些信息。比如说,它可以承载对一个activity 的请求,让它为用户显示一张图片,或者让用户编辑一些文本。而对于广播接收器而言,Intent对象指明了声明的行为。比如,它可以对所有感兴趣的对象声明照相按钮被按下。 对于每种组件来说,激活的方法是不同的: 通过传递一个Intent对象至Context.startActivity()或Activity.startActivityForResult()以载入(或指定新工作给)一个activity。相应的activity可以通过调用 getIntent() 方法来查看激活它的intent。Android通过调用activity的onNewIntent()方法来传递给它继发的intent。 一个activity经常启动了下一个。如果它期望它所启动的那个activity返回一个结果,它会以调用startActivityForResult()来取代startActivity()。比如说,如果它启动了另外一个activity以使用户挑选一张照片,它也许想知道哪张照片被选中了。结果将会被封装在一个Intent对象中,并传递给发出调用的activity的onActivityResult() 方法。 通过传递一个Intent对象至Context.startService()将启动一个服务(或给予正在运行的服务以一个新的指令)。Android调用服务的onStart()方法并将Intent对象传递给它。 与此类似,一个Intent可以被调用组件传递给 Context.bindService()以获取一个正在运行的目标服务的连接。这个服务会经由onBind() 方法的调用获取这个Intent对象(如果服务尚未启动,bindService()会先启动它)。比如说,一个activity可以连接至前述的音乐回放服务,并提供给用户一个可操作的(用户界面)以对回放进行控制。这个activity可以调用 bindService() 来建立连接,然后调用服务中定义的对象来影响回放。 应用程序可以凭借将Intent对象传递给 Context.sendBroadcast() ,Context.sendOrderedBroadcast(), 以及Context.sendStickyBroadcast()和其它类似方法来产生一个广播。Android会调用所有对此广播有兴趣的广播接收器的 onReceive()方法将intent传递给它们。 Intent对象包含的内容 在Intent类的Java源代码中定义了Intent相关内容的变量,如下: // Action private String mAction; // Data private Uri mData; private String mType; private String mPackage; // ComponentName private ComponentName mComponent; // Flag private int mFlags; // category private HashSet<String> mCategories; // extras private Bundle mExtras; componentName(组件名称),指定Intent的目标组件的类名称。组件名称是可选的,如果填写,Intent对象会发送给指定组件名称的组件,否则也可以通过其他Intent信息定位到适合的组件。组件名称是个ComponentName类型的对象。 用法: Intent intent = new Intent(); // 构造的参数为当前Context和目标组件的类路径名 ComponentName cn = new ComponentName(HelloActivity.this, "com.byread.activity.OtherActivity"); intent.setComponent(cn); startActivity(intent); 相当于以下常用方法: Intent intent = new Intent(); intent.setClass(HelloActivity.this, OtherActivity.class); startActivity(intent); Intent类中也包含一个初始化ComponentName的构造函数: public Intent(Context packageContext, Class<?> cls) { mComponent = new ComponentName(packageContext, cls); } action(动作), 指定Intent的执行动作,比如调用拨打电话组件。 public Intent(String action) { mAction = action; } data(数据),起到表示数据和数据MIME类型的作用。不同的action是和不同的data类型配套的,通过设置data的Uri来获得。 public Intent(String action, Uri uri) { mAction = action; mData = uri; } 比如调用拨打电话组件: Uri uri = Uri.parse("tel:10086"); // 参数分别为调用拨打电话组件的Action和获取Data数据的Uri Intent intent = new Intent(Intent.ACTION_DIAL, uri); startActivity(intent); category(类别),被执行动作的附加信息。例如应用的启动Activity在intent-filter中设置category。 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> extras(附加信息),为处理Intent组件提供附加的信息。可通过putXX()和getXX()方法存取信息;也可以通过创建Bundle对象,再通过putExtras()和getExtras()方法来存取。 flags(标记),指示Android如何启动目标Activity,设置方法为调用Intent的setFlags方法。常用的Flags参数有: FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NO_HISTORY FLAG_ACTIVITY_SINGLE_TOP Intent的投递 显式方式:直接设置目标组件的ComponentName,用于一个应用内部的消息传递,比如启动另一个Activity或者一个services。 通过Intent的setComponent和setClass来制定目标组件的ComponentName。 隐式方式:ComponentName为空,用于调用其他应用中的组件。需要包含足够的信息,这样系统才能根据这些信息使用intent filter在所有的组件中过滤action、data或者category来匹配目标组件。可参考Android中Activity组件详解(5.Activity的Intent Filter) 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配; 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配; 如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme (比如 http: 或者mailto: ) 进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中; 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如 Intent中包含了两个类别:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。 Intent调用常见系统组件 // 调用浏览器 Uri webViewUri = Uri.parse("http://blog.csdn.net/zuolongsnail"); Intent intent = new Intent(Intent.ACTION_VIEW, webViewUri); // 调用地图 Uri mapUri = Uri.parse("geo:100,100"); Intent intent = new Intent(Intent.ACTION_VIEW, mapUri); // 播放mp3 Uri playUri = Uri.parse("file:///sdcard/test.mp3"); Intent intent = new Intent(Intent.ACTION_VIEW, playUri); intent.setDataAndType(playUri, "audio/mp3"); // 调用拨打电话 Uri dialUri = Uri.parse("tel:10086"); Intent intent = new Intent(Intent.ACTION_DIAL, dialUri); // 直接拨打电话,需要加上权限<uses-permission id="android.permission.CALL_PHONE" /> Uri callUri = Uri.parse("tel:10086"); Intent intent = new Intent(Intent.ACTION_CALL, callUri); // 调用发邮件(这里要事先配置好的系统Email,否则是调不出发邮件界面的) Uri emailUri = Uri.parse("mailto:zuolongsnail@163.com"); Intent intent = new Intent(Intent.ACTION_SENDTO, emailUri); // 直接发邮件 Intent intent = new Intent(Intent.ACTION_SEND); String[] tos = { "zuolongsnail@gmail.com" }; String[] ccs = { "zuolongsnail@163.com" }; intent.putExtra(Intent.EXTRA_EMAIL, tos); intent.putExtra(Intent.EXTRA_CC, ccs); intent.putExtra(Intent.EXTRA_TEXT, "the email text"); intent.putExtra(Intent.EXTRA_SUBJECT, "subject"); intent.setType("text/plain"); Intent.createChooser(intent, "Choose Email Client"); // 发短信 Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra("sms_body", "the sms text"); intent.setType("vnd.android-dir/mms-sms"); // 直接发短信 Uri smsToUri = Uri.parse("smsto:10086"); Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri); intent.putExtra("sms_body", "the sms text"); // 发彩信 Uri mmsUri = Uri.parse("content://media/external/images/media/23"); Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra("sms_body", "the sms text"); intent.putExtra(Intent.EXTRA_STREAM, mmsUri); intent.setType("image/png"); // 卸载应用 Uri uninstallUri = Uri.fromParts("package", "com.app.test", null); Intent intent = new Intent(Intent.ACTION_DELETE, uninstallUri); // 安装应用 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File("/sdcard/test.apk"), "application/vnd.android.package-archive"); // 在Android Market中查找应用 Uri uri = Uri.parse("market://search?q=愤怒的小鸟"); Intent intent = new Intent(Intent.ACTION_VIEW, uri);

优秀的个人博客,低调大师

iOS开发之多媒体播放

iOS sdk中提供了很多方便的方法来播放多媒体。本文将利用这些SDK做一个demo,来讲述一下如何使用它们来播放音频文件。 AudioToolbox framework 使用AudioToolbox framework。这个框架可以将比较短的声音注册到 system sound服务上。被注册到system sound服务上的声音称之为 system sounds。它必须满足下面几个条件。 1、播放的时间不能超过30秒 2、数据必须是 PCM或者IMA4流格式 3、必须被打包成下面三个格式之一:Core Audio Format (.caf), Waveform audio (.wav),或者 Audio Interchange File (.aiff) 声音文件必须放到设备的本地文件夹下面。通过AudioServicesCreateSystemSoundID方法注册这个声音文件,AudioServicesCreateSystemSoundID需要声音文件的url的CFURLRef对象。看下面注册代码: #import<AudioToolbox/AudioToolbox.h>@interface MediaPlayerViewController : UIViewController { IBOutlet UIButton *audioButton; SystemSoundID shortSound; } - (id)init { self = [super initWithNibName:@"MediaPlayerViewController" bundle:nil];if (self) {// Get the full path of Sound12.aif NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"Sound12" ofType:@"aif"];// If this file is actually in the bundle...if (soundPath) {// Create a file URL with this path NSURL *soundURL = [NSURL fileURLWithPath:soundPath];// Register sound file located at that URL as a system sound OSStatus err = AudioServicesCreateSystemSoundID((CFURLRef)soundURL, &shortSound);if (err != kAudioServicesNoError) NSLog(@"Could not load %@, error code: %d", soundURL, err); } }return self; } 这样就可以使用下面代码播放声音了: - (IBAction)playShortSound:(id)sender { AudioServicesPlaySystemSound(shortSound); } 使用下面代码,还加一个震动的效果: - (IBAction)playShortSound:(id)sender { AudioServicesPlaySystemSound(shortSound); AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } AVFoundation framework 对于压缩过Audio文件,或者超过30秒的音频文件,可以使用AVAudioPlayer类。这个类定义在AVFoundation framework中。 下面我们使用这个类播放一个mp3的音频文件。首先要引入AVFoundation framework,然后MediaPlayerViewController.h中添加下面代码: #import<AVFoundation/AVFoundation.h>@interface MediaPlayerViewController : UIViewController <AVAudioPlayerDelegate> { IBOutlet UIButton *audioButton; SystemSoundID shortSound; AVAudioPlayer *audioPlayer; AVAudioPlayer类也是需要知道音频文件的路径,使用下面代码创建一个AVAudioPlayer实例: - (id)init { self = [super initWithNibName:@"MediaPlayerViewController" bundle:nil];if (self) { NSString *musicPath = [[NSBundle mainBundle] pathForResource:@"Music" ofType:@"mp3"];if (musicPath) { NSURL *musicURL = [NSURL fileURLWithPath:musicPath]; audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil]; [audioPlayer setDelegate:self]; } NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"Sound12" ofType:@"aif"]; 我们可以在一个button的点击事件中开始播放这个mp3文件,如: - (IBAction)playAudioFile:(id)sender {if ([audioPlayer isPlaying]) {// Stop playing audio and change text of button [audioPlayer stop]; [sender setTitle:@"Play Audio File" forState:UIControlStateNormal]; }else {// Start playing audio and change text of button so// user can tap to stop playback [audioPlayer play]; [sender setTitle:@"Stop Audio File" forState:UIControlStateNormal]; } } 这样运行我们的程序,就可以播放音乐了。 这个类对应的AVAudioPlayerDelegate有两个委托方法。一个是 audioPlayerDidFinishPlaying:successfully: 当音频播放完成之后触发。当播放完成之后,可以将播放按钮的文本重新回设置成:Play Audio File - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { [audioButton setTitle:@"Play Audio File" forState:UIControlStateNormal]; } 另一个是audioPlayerEndInterruption:,当程序被应用外部打断之后,重新回到应用程序的时候触发。在这里当回到此应用程序的时候,继续播放音乐。 - (void)audioPlayerEndInterruption:(AVAudioPlayer *)player { [audioPlayer play]; } MediaPlayer framework 播放电影文件: iOS sdk中可以使用MPMoviePlayerController来播放电影文件。但是在iOS设备上播放电影文件有严格的格式要求,只能播放下面两个格式的电影文件。 • H.264 (Baseline Profile Level 3.0) • MPEG-4 Part 2 video (Simple Profile) 幸运的是你可以先使用iTunes将文件转换成上面两个格式。 MPMoviePlayerController还可以播放互联网上的视频文件。但是建议你先将视频文件下载到本地,然后播放。如果你不这样做,iOS可能会拒绝播放很大的视频文件。 这个类定义在MediaPlayer framework中。在你的应用程序中,先添加这个引用,然后修改MediaPlayerViewController.h文件。 #import<MediaPlayer/MediaPlayer.h>@interface MediaPlayerViewController : UIViewController <AVAudioPlayerDelegate> { MPMoviePlayerController *moviePlayer; 下面我们使用这个类来播放一个.m4v 格式的视频文件。与前面的类似,需要一个url路径。 - (id)init { self = [super initWithNibName:@"MediaPlayerViewController" bundle:nil];if (self) { NSString *moviePath = [[NSBundle mainBundle] pathForResource:@"Layers" ofType:@"m4v"];if (moviePath) { NSURL *movieURL = [NSURL fileURLWithPath:moviePath]; moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieURL]; } MPMoviePlayerController有一个视图来展示播放器控件,我们在viewDidLoad方法中,将这个播放器展示出来。 - (void)viewDidLoad { [[self view] addSubview:[moviePlayer view]];float halfHeight = [[self view] bounds].size.height /2.0;float width = [[self view] bounds].size.width; [[moviePlayer view] setFrame:CGRectMake(0, halfHeight, width, halfHeight)]; } 还有一个MPMoviePlayerViewController类,用于全屏播放视频文件,用法和MPMoviePlayerController一样。 MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL]; [viewController presentMoviePlayerViewControllerAnimated:playerViewController]; 我们在听音乐的时候,可以用iphone做其他的事情,这个时候需要播放器在后台也能运行,我们只需要在应用程序中做个简单的设置就行了。 1、在Info property list中加一个 Required background modes节点,它是一个数组,将第一项设置成设置App plays audio。 2、在播放mp3的代码中加入下面代码: if (musicPath) { NSURL *musicURL = [NSURL fileURLWithPath:musicPath]; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:musicURL error:nil]; [audioPlayer setDelegate:self]; } 在后台运行的播放音乐的功能在模拟器中看不出来,只有在真机上看效果。 总结:本文通过例子详细讲解了iOS sdk中用于播放音频文件的类,文章后面有本文的代码提供下载。 代码:http://files.cnblogs.com/zhuqil/MediaPlayer.zip 本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2011/07/23/2115021.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

iOS开发之邮件发送代码

邮件发送功能是由MessageUI Framework提供的,这个框架是iPhone sdk中最简单的框。由一个类、一个视图控制器,一个protocol组成。 一、创建视图控制器: MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init]; mc.mailComposeDelegate = self ; 二、设置邮件主题: [mc setSubject:@"Hello, World!"]; 三、设置收件人,收件人有三种: 1、设置主收件人 [mc setToRecipients:[ NSArray arrayWithObjects:@ "zhuqi0@126.com" , "@dave@iphonedevbook.com" , nil ]; 2、设置cc [mc setCcRecipients:[NSArray arrayWithObject:@"zhuqil@163.com"]]; 3、设置bcc [mc setBccRecipients:[NSArray arrayWithObject:@"secret@gmail.com"]]; 四、设置邮件主体,有两种格式。 一种是纯文本 [mc setMessageBody:@"Watson!!!\n\nCome here, I need you!" isHTML:NO]; 一个是html格式 [mc setMessageBody:@ "<HTML><B>Hello, Joe!</B><BR/>What do you know?</HTML>" isHTML: YES ]; 五、添加附件 添加附件需要三个参数,一个是NSData类型的附件,一个是mimetype,一个附件的名称。 NSString *path = [[NSBundle mainBundle] pathForResource:@"blood_orange" ofType:@"png"]; NSData *data = [NSData dataWithContentsOfFile:path]; [mc addAttachmentData:data mimeType:@"image/png" fileName:@"blood_orange"]; 六、视图呈现 [self presentModalViewController:mc animated:YES]; [mc release]; 七、视图控制器的委托方法 邮件视图控制器的委托方法包含在MFMailComposeViewControllerDelegate中,无论用户是否发送或取消发送,不论系统是否能够发送邮件, 方法 mailComposeController:didFinishWithResult:error: gets called都会被调用。 - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { switch (result) { case MFMailComposeResultCancelled: NSLog(@"Mail send canceled..."); break; case MFMailComposeResultSaved: NSLog(@"Mail saved..."); break; case MFMailComposeResultSent: NSLog(@"Mail sent..."); break; case MFMailComposeResultFailed: NSLog(@"Mail send errored: %@...", [error localizedDescription]); break; default: break; } [self dismissModalViewControllerAnimated:YES]; } 本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2011/07/21/2112816.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册