当前位置:  编程技术>移动开发
本页文章导读:
    ▪创办与删除快捷方式        创建与删除快捷方式创建与删除快捷方式: 权限: <!-- 创建与删除快捷方式 -->     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />     <uses-permission android:na.........
    ▪ 设立Activity使用系统壁纸作为背景        设置Activity使用系统壁纸作为背景在AndroidManifest.xml中,       android:name=".HomeActivity"          <action android:name="android.intent.action.MAIN" />          <category android:name="android..........
    ▪ GUI为啥不设计为多线程       GUI为什么不设计为多线程在我们这批新人转正评审的时候,我师父问了我的小伙伴一个问题:为什么一些更新界面的方法只能在主线程中调用?师父没有问我这个问题,让知其然但不知其所.........

[1]创办与删除快捷方式
    来源: 互联网  发布时间: 2014-02-18
创建与删除快捷方式
创建与删除快捷方式:

权限:
<!-- 创建与删除快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

public class ShortCutUtil {

/***
* 桌面快捷方式相关
* @author chenzheng_java
* @since 2011/07/20
*/

// 创建桌面快捷方式需要的intent字符串,此字符串为指定值,不能修改
private static final String ACTION_INSTALL_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";
// 删除桌面快捷方式需要的intent字符串,此字符串为指定值,不能修改
private static final String ACTION_UNINSTALL_SHORTCUT = "com.android.launcher.action.UNINSTALL_SHORTCUT";
private static final String SHORTCUT_DUPLICATE = "duplicate";
private static final String shortcut_actionString = "cn.com.chenzheng_java.shortcut";

/***
* 创建一个快捷方式到桌面
* @param shortcutName
*            快捷方式的名称
* @param activity
*            一个Activity对象
* @param iconId
*            当做快捷图标的图片的索引值
*/
public static void createShortcut(String shortcutName, Activity activity,
int iconId) {

Intent shortcut_intent = new Intent();
shortcut_intent.setAction(ACTION_INSTALL_SHORTCUT);// 发送此广播,则系统会为我们创建快捷方式到桌面
shortcut_intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName);// 设置快捷方式的名称

shortcut_intent.putExtra(SHORTCUT_DUPLICATE, false);// 是否可以重复创建

Intent intent = new Intent();
// intent.setClass(activity, activity.getClass()); 如此也可以
ComponentName componentName = new ComponentName(activity, activity
.getClass());
intent.setComponent(componentName);

intent.setAction(shortcut_actionString);
shortcut_intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);// 设置当快捷方式被点击时触发哪个intent

// 快捷方式的图标
Parcelable icon = ShortcutIconResource.fromContext(activity, iconId);
shortcut_intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
activity.sendBroadcast(shortcut_intent);// 向系统发送广播,创建快捷方式

}

/***
* 删除当前应用的快捷方式
* @param shortcutName
*            快捷方式的名称
* @param activity
*            当前上下文
*/
public static void deleteShortcut(String shortcutName, Activity activity) {

Intent shortcut = new Intent(ACTION_UNINSTALL_SHORTCUT);
// 显示的名字
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName);
// 这里的intent要和创建时的intent设置一致
// Intent intent = new Intent(activity, activity.getClass());
Intent intent = new Intent();
ComponentName componentName = new ComponentName(activity, activity
.getClass());
intent.setComponent(componentName);
intent.setAction(shortcut_actionString);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);

// 发送广播以删除shortcut
activity.sendBroadcast(shortcut);
// Toast.makeText(activity, "删除自身快捷方式成功", Toast.LENGTH_SHORT).show();

}

/***
* 删除快捷方式
* @param shortcutName
*            快捷方式名称
* @param componentName
* @param addActionString
* @param context
*/
public static void deleteShortcut(String shortcutName,
ComponentName componentName, String addActionString, Context context) {
Intent shortIntent = new Intent();
shortIntent.setAction(ACTION_UNINSTALL_SHORTCUT);
shortIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName);

Intent intent = new Intent();
intent.setComponent(componentName);
intent.setAction(addActionString);
shortIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);

context.sendBroadcast(shortIntent);

}

/***
* 删除某个快捷方式
* @param intent
*            关联快捷方式与应用程序之间的intent
* @param shortcutName 快捷方式的名称
* @param context 上下文
*/
public static void deleteShortcut(Intent intent, String shortcutName,
Context context) {

Intent shortIntent = new Intent();
shortIntent.setAction(ACTION_UNINSTALL_SHORTCUT);
shortIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName);
shortIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
context.sendBroadcast(shortIntent);

}

}

    
[2] 设立Activity使用系统壁纸作为背景
    来源: 互联网  发布时间: 2014-02-18
设置Activity使用系统壁纸作为背景

在AndroidManifest.xml中,

<activity
      android:label="@string/app_name"
      android:name=".HomeActivity"
      android:theme="@style/android:Theme.Wallpaper" >
      <intent-filter >
         <action android:name="android.intent.action.MAIN" />
         <category android:name="android.intent.category.LAUNCHER" />
         <category android:name="android.intent.category.HOME" />
         <category android:name="android.intent.category.DEFAULT" />
         <category android:name="android.intent.category.MONKEY" />
      </intent-filter>  
</activity>

关键是:android:theme="@style/android:Theme.Wallpaper"

第一次不用系统壁纸,可以在代码中设置自己的壁纸:
setWallpaper(Bitmap); //Bitmap----->资源图片




    
[3] GUI为啥不设计为多线程
    来源: 互联网  发布时间: 2014-02-18
GUI为什么不设计为多线程

在我们这批新人转正评审的时候,我师父问了我的小伙伴一个问题:为什么一些更新界面的方法只能在主线程中调用?师父没有问我这个问题,让知其然但不知其所以然的我有种侥幸逃过一难的心情。我想如果回答那是因为Android GUI库是单线程消息机制的,更新界面的操作必须放到主线程中执行,那师父可能继续问为什么Android GUI要设计成单线程的,我就不知道了。

为什么它非得设计为单线程的?多线程不是更好吗?带着点好奇感和求知欲以及鄙视权威的无畏精神我在google中展开了搜索,并最终找到了一个令我满意的解释,欣喜之余将我的理解分析给大家。

单线程消息队列机制

首先我还是说一下我对GUI单线程消息队列机制的理解,这是我大学里几年编程经验赚来的知其然的部分。

Android、Swing、MFC等的GUI库都使用单线程消息队列机制来处理绘制界面、事件响应等消息,在这种设计中,每个待处理的任务都被封装成一个消息添加到消息队列中。消息队列是线程安全的(消息队列自己通过加锁等机制保证消息不会在多线程竞争中丢失),任何线程都可以添加消息到这个队列中,但是只有主线程(UI线程)从中取出消息,并执行消息的响应函数,这就保证了只有主线程才去执行这些操作。

单线程消息队列机制存在一个问题:消息响应函数中不能有耗时长的、计算密集型的操作,因为主线程在努力地处理这样的操作的时候就无法去处理其它的积压在消息队列中的绘制消息、事件消息了(一个消息处理完了主线程才会去队列中取下一个消息),这时候就会出现按键无响应、点击无反应的情况。

但这个问题有完美的,我们可以在消息响应函数中启动另一个工作线程(Worker Thread)来执行耗时操作,这样在线程启动起来后这个消息就算处理完了,主线程可以取下一个消息了,这时候主线程和还未执行完计算任务的工作线程就在操作系统的调度下并驾齐驱地狂奔了(调度算法会保证两个线程并发或并行地执行,不会专宠某个线程)。

一般我们在耗时任务执行完后还要更新界面展示计算的结果,由于我们不能直接在工作线程中更新界面,所以可能有些小伙伴直接在消息响应函数中线程start后就接着调用join来等待线程结束以更新界面,这其实相当于把耗时任务直接放在主线程去执行,因为在消息响应函数中join其实就是主线程在join,积压的消息是得不到处理的。正确的处理办法是将耗时任务改为异步通知机制,即工作线程向消息队列中添加消息以通知主线程耗时任务完成了,这样主线程在启动工作线程后就不需要主动地去调查任务的进展了,“任务结束的时候它会通知我的”,主线程如是说。

工作线程向主线程的消息队列添加消息的常用方法如下:

l Android:Acitvity.runOnUiThead、Handler.post、AsyncTask

l Swing:SwingUtilities.invokeLater

l Win32、MFC:自定义用户消息,在工作线程中PostMessage

GUI为什么不设计为多线程

大部分的GUI toolkits都是设计为上面的单线程消息队列机制,为什么不设计为多线程的呢?如果GUI是多线程的,CPU又是多核的话,多个CPU核心可以并行地执行绘制等操作,界面响应的速度应该是成倍提升的;而且就算是其中有多线程共享的资源加锁不就行了吗?

在google搜索的过程中我看到了负责Swing开发的一个大师的一篇博客《Multithreaded toolkits: A failed dream?》:

https://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html

从中我了解到开发多线程的GUI toolkits是一件吃力不讨好的事,不仅开发难度大Bug多多,用起来也未必可以获得理想中的效果,其中的死锁和竞争,大师们也感到头疼。

多线程GUI加锁困难

为什么这么困难?大师讲了一个例子,我们通过用户级的代码去改变界面如TextView.setText走的是个自顶向下的流程:

而系统底层发起的如键盘事件、点击事件走的是个自底向上的流程:

 

这样就麻烦了,因为为了避免死锁,每个流程都要走一样的加锁顺序,而GUI中的这两个流程却是完全相反的,如果每一层都有一个锁的话加锁就是个难以完成的任务了,而如果每一层都共用一个锁的话,那就跟单线程没区别了。

于是GUI toolkits的开发者就“不负责任”地把GUI设计成了单线程消息队列机制,然后他们还说界面更新一般不是瓶颈,单线程足够了。然后我瞬间想到了3D游戏,单线程对于3D应该是很吃力的,但实际上负责3D绘制的是显卡的GPU,GPU不像CPU那样事无巨细、事必亲躬、鞠躬尽瘁、死而后已,只负责画好它的图就可以了,所以并行起来不是件困难的事。


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