Android中的Theme和Style

| 收藏本文 下载本文 作者:YxE

下面小编给大家带来Android中的Theme和Style(共含10篇),希望能帮助到大家!同时,但愿您也能像本文投稿人“YxE”一样,积极向本站投稿分享好文章。

Android中的Theme和Style

篇1:Android中的Theme和Style

1.首先,Theme属性详解:

android:theme=“@android:style/Theme.Dialog” //Activity显示为对话框模式

android:theme=“@android:style/Theme.NoTitleBar” //不显示应用程序标题栏

android:theme=“@android:style/Theme.NoTitleBar.Fullscreen” //不显示应用程序标题栏,并全屏

android:theme=“Theme.Light ” //背景为白色

android:theme=“Theme.Light.NoTitleBar” //白色背景并无标题栏

android:theme=“Theme.Light.NoTitleBar.Fullscreen” //白色背景,无标题栏,全屏

android:theme=“Theme.Black” //背景黑色

android:theme=“Theme.Black.NoTitleBar” //黑色背景并无标题栏

android:theme=“Theme.Black.NoTitleBar.Fullscreen” //黑色背景,无标题栏,全屏

android:theme=“Theme.Wallpaper” //用系统桌面为应用程序背景

android:theme=“Theme.Wallpaper.NoTitleBar” //用系统桌面为应用程序背景,且无标题栏

android:theme=“Theme.Wallpaper.NoTitleBar.Fullscreen” //用系统桌面为应用程序背景,无标题栏,全屏

android:theme=“Theme.Translucent” //透明背景

android:theme=“Theme.Translucent.NoTitleBar” //透明背景并无标题

android:theme=“Theme.Translucent.NoTitleBar.Fullscreen” //透明背景并无标题,全屏

android:theme=“Theme.Panel ” //面板风格显示

android:theme=“Theme.Light.Panel” //平板风格显示

2.其次,Theme和Style区别:

前者主要用于Application和Activity,后者主要用于View,

Android中的Theme和Style

篇2:Android学习笔记之Theme主题的修改设置

(1)布局文件

(2)在values中新建xml文件

fill_parentwrap_contentmonospace#00FF0020sp#00FF00wrap_contentwrap_content48dp148dp#ACBDEC#b0b0ff@color/custom_theme_color@color/custom_theme_color

(3)如果要修改Android默认的主题需要在清单文件中修改,下图圈出的位置就是需要修改的地方

(4)其他问阿金都可以默认无需修改!

篇3:Android中AsyncTask使用

一、AsyncTask的作用:

代替Thread+Handler的组合,使创建异步任务变得简单,

AsyncTask执行后台操作,并在用户界面上发布结果,而不必处理线程。

二、AsyncTask的定义:

public abstract class AsyncTask

extends Object

AsyncTask必须子类可以使用。子类将覆盖至少一个方法(doInBackground执行异步任务),通常会覆盖一次(onPostExecute显示结果,更新UI)

AsyncTask三种类型如下:

》Params,参数的类型发送到任务执行时。

》Progress,在后台计算过程中公布的进度单元类型。

》Result,计算结果的类型。

不是所有类型都是异步任务所使用的。要标记为未使用的类型,设置该类型Void:

三、AsyncTask的方法:

1、onPreExecute

在任务开始后立即调用,在UI线程执行。这一步通常用于设置任务,例如在用户界面中初始化进度条。

2、doInBackground(Params...)

后台线程调用onPreExecute()完成后立即执行。这一步后台进程执行,可能会花费很长时间。

3、onProgressUpdate(Progress...)

调用publishProgress,在UI线程上执行,

这种方法是用来显示用户进度界面,后台进程仍在执行。例如,它可用于显示一个进度条或在文本中显示日志。

4、onPostExecute(Result)

后台进程处理完后,在UI线程上执行。后台进程的结果被传递到这一步作为参数。

常用的写法如下:

class MyTask extends AsyncTask { @Override protected String doInBackground(String... params) { //执行异步任务 int n = 10; //调用publishProgress公布进度,最后onProgressUpdate方法将被执行 publishProgress(n); Thread.sleep(500);return null; } @Override protected void onPostExecute(String result) { //更新UI,显示结果 } @Override protected void onProgressUpdate(Integer... values) { //更新进度信息 }

new MyTask().execute();//执行任务

三、AsyncTask的规则:

1、任务实例必须在用户界面线程中创建。

2、execute(Params... params)方法必须在UI线程中调用。

3、不要手动调用onPreExecute,doInBackground,onProgressUpdate,onPostExecute这些方法

4、一个任务实例只能执行一次,如果执行第二次将会抛出异常

篇4:Android中进程管理

在android中,进程这个概念被淡化了,我们知道Android的每一个应用都是运行在一个独立的DVM中,他们之间互不影响;应用退出之后,并没有立马杀死进程,进程依然停留在内存中,这么做的目的是为了提高下次启动时的速度,而在Android中管理进程的模块是AMS,主要有LRU weight,OOM adj,Low Memory Killer共同来完成进程的管理。

1 LRU weightLRU(最近最少使用)weight 主要用来衡量LRU的权重,在android进程启动之后,会以ProcessRecord类型的方式创建一个实例,保存到AMS的mLruProcesses变量中,mLurProcesses会以LRU的顺序来存储进程信息。当有一下情况时会更新mLruProcesses: 1.应用程序异常退出 2.调用AMS显式杀死进程 3.启动和调度四大组件 这里以启动和调度四大组件为例,它最终会调用AMS的updateLruProcessLock方法:

final void updateLruProcessLocked(ProcessRecord app,boolean oomAdj, boolean updateActivityTime) { mLruSeq++;//lru序号加一 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); }

先将LRU序号加一,用于标记一次更新LRU的操作,然后调用updateLruProcessInternalLocked:

private final void updateLruProcessInternalLocked(ProcessRecord app,boolean oomAdj, boolean updateActivityTime, int bestPos) { // put it on the LRU to keep track of when it should be exited. int lrui = mLruProcesses.indexOf(app); if (lrui >= 0) mLruProcesses.remove(lrui); int i = mLruProcesses.size()-1; int skipTop = 0; app.lruSeq = mLruSeq; // compute the new weight for this process. if (updateActivityTime) {app.lastActivityTime = SystemClock.uptimeMillis(); } if (app.activities.size() > 0) {// If this process has activities, we more strongly want to keep// it around.app.lruWeight = app.lastActivityTime; } else if (app.pubProviders.size() > 0) {// If this process contains content providers, we want to keep// it a little more strongly.app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;// Also don't let it kick out the first few real hidden processes.skipTop = ProcessList.MIN_HIDDEN_APPS; } else {// If this process doesn't have activities, we less strongly// want to keep it around, and generally want to avoid getting// in front of any very recently used activities.app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;// Also don't let it kick out the first few real hidden processes.skipTop = ProcessList.MIN_HIDDEN_APPS; } while (i >= 0) {ProcessRecord p = mLruProcesses.get(i);// If this app shouldn't be in front of the first N background// apps, then skip over that many that are currently hidden.if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { skipTop--;}if (p.lruWeight <= app.lruWeight || i < bestPos) { mLruProcesses.add(i+1, app);//添加到mLruProcesses合适的位置 break;}i--; } if (i < 0) {mLruProcesses.add(0, app); } // 如果这个进程之后总有cotent provider或者Service,重新计算 // If the app is currently using a content provider or service, // bump those processes as well. if (app.connections.size() > 0) {for (ConnectionRecord cr : app.connections) { if (cr.binding != null && cr.binding.service != null&& cr.binding.service.app != null&& cr.binding.service.app.lruSeq != mLruSeq) { updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,updateActivityTime, i+1); }} } if (app.conProviders.size() > 0) {for (ContentProviderRecord cpr : app.conProviders.keySet()) { if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) { updateLruProcessInternalLocked(cpr.proc, oomAdj, updateActivityTime, i+1); }} } if (oomAdj) {updateOomAdjLocked();调用updateOomAdjLocked 更新oom adj值 } }

这个函数主要作用 1.为该进程计算LRU序列号和LRU weight 2.根据计算出来的LRU weight,将该进程信息插入到mLRUProcesses合适的位置之中 3.如果该进程之中有content provider或者service,重新计算LRU weight 4.判断是否需要调用updateOomAdjLocked函数来更新oom adj的值

到此为止updateLruProcessLocked结束,可以看出,这个函数只是调整进程的LRU weight和在mLruProcesses中的位置,并没有直接参与进程的管理,真正参与进程管理的是updateOomAdjLocked函数,这个函数用来更新oom adj的值,这个值影响着进程的回收

2 OOM adjOOM adj 定义了一系列的OOM的调整级别,从-17到15。在Low Memory Killer机制中已经介绍过,这里看一下Android中定义了13个调整级别,在ProcessList文件中

class ProcessList { // OOM adjustments for processes in various states: // This is a process without anything currently running in it. Definitely // the first to go! Value set in system/rootdir/init.rc on startup. // This value is initalized in the constructor, careful when refering to // this static variable externally. static final int EMPTY_APP_ADJ = 15; // This is a process only hosting activities that are not visible, // so it can be killed without any disruption. Value set in // system/rootdir/init.rc on startup. static final int HIDDEN_APP_MAX_ADJ = 15; static int HIDDEN_APP_MIN_ADJ = 7; // This is a process holding the home application -- we want to try // avoiding killing it, even if it would normally be in the background, // because the user interacts with it so much. static final int HOME_APP_ADJ = 6; // This is a process holding a secondary server -- killing it will not // have much of an impact as far as the user is concerned. Value set in // system/rootdir/init.rc on startup. static final int SECONDARY_SERVER_ADJ = 5; // This is a process currently hosting a backup operation. Killing it // is not entirely fatal but is generally a bad idea. static final int BACKUP_APP_ADJ = 4; // This is a process with a heavy-weight application. It is in the // background, but we want to try to avoid killing it. Value set in // system/rootdir/init.rc on startup. static final int HEAVY_WEIGHT_APP_ADJ = 3; // This is a process only hosting components that are perceptible to the // user, and we really want to avoid killing them, but they are not // immediately visible. An example is background music playback. Value set in // system/rootdir/init.rc on startup. static final int PERCEPTIBLE_APP_ADJ = 2; // This is a process only hosting activities that are visible to the // user, so we'd prefer they don't disappear. Value set in // system/rootdir/init.rc on startup. static final int VISIBLE_APP_ADJ = 1; // This is the process running the current foreground app. We'd really // rather not kill it! Value set in system/rootdir/init.rc on startup. static final int FOREGROUND_APP_ADJ = 0; // This is a process running a core server, such as telephony. Definitely // don't want to kill it, but doing so is not completely fatal. static final int CORE_SERVER_ADJ = -12; // The system process runs at the default adjustment. static final int SYSTEM_ADJ = -16; .....}

AMS提供了函数来改变这个值:updateOomAdjLocked

final void updateOomAdjLocked() { final ActivityRecord TOP_ACT = resumedAppLocked(); final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; if (false) {RuntimeException e = new RuntimeException();e.fillInStackTrace();Slog.i(TAG, updateOomAdj: top= + TOP_ACT, e); } mAdjSeq++; // Let's determine how many processes we have running vs. // how many slots we have for background processes; we may want // to put multiple processes in a slot of there are enough of // them. int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1; int factor = (mLruProcesses.size()-4)/numSlots; if (factor < 1) factor = 1; int step = 0; int numHidden = 0; // First update the OOM adjustment for each of the // application processes based on their current state. int i = mLruProcesses.size(); int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; int numBg = 0; while (i > 0) {i--;ProcessRecord app = mLruProcesses.get(i);//Slog.i(TAG, OOM + app + : cur hidden= + curHiddenAdj); //调用重载函数updateOomAdjLocked,更新OOM adj的值updateOomAdjLocked(app, curHiddenAdj, TOP_APP);if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ && app.curAdj == curHiddenAdj) { step++; if (step >= factor) { step = 0; curHiddenAdj++; }}if (!app.killedBackground) { // 如果adj的值大于等于ProcessList.HIDDEN_APP_MIN_ADJ if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) { numHidden++; if (numHidden > mProcessLimit) {Slog.i(TAG, No longer want + app.processName + (pid + app.pid + ): hidden # + numHidden);EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, app.processName, app.setAdj, too many background);app.killedBackground = true;Process.killProcessQuiet(app.pid);//杀死进程 } else {numBg++; } } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) { numBg++; }} } ...... }

其中调用了重载函数updateOomAdjLocked,具体代码如下:

private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { app.hiddenAdj = hiddenAdj; if (app.thread == null) {return false; } final boolean wasKeeping = app.keeping; boolean success = true; // 1调用computeOomAdjLocked方法计算oom adj的值 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); if (app.curRawAdj != app.setRawAdj) {if (false) { // Removing for now. Forcing GCs is not so useful anymore // with Dalvik, and the new memory level hint facility is // better for what we need to do these days. if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ&& app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) { // If this app is transitioning from foreground to // non-foreground, have it do a gc. scheduleAppGcLocked(app); } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ&& app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) { // Likewise do a gc when an app is moving in to the // background (such as a service stopping). scheduleAppGcLocked(app); }}if (wasKeeping && !app.keeping) { // This app is no longer something we want to keep. Note // its current wake lock time to later know to kill it if // it is not behaving well. BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); synchronized (stats) { app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, app.pid, SystemClock.elapsedRealtime()); } app.lastCpuTime = app.curCpuTime;}app.setRawAdj = app.curRawAdj; } if (app.curAdj != app.setAdj) {// 2 调用setOomAdj来修改进程的oom adj的值 if (Process.setOomAdj(app.pid, app.curAdj)) { if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( TAG, Set app + app.processName + oom adj to + app.curAdj + because + app.adjType); app.setAdj = app.curAdj;} else { success = false; Slog.w(TAG, Failed setting oom adj of + app + to + app.curAdj);} } if (app.setSchedGroup != app.curSchedGroup) {app.setSchedGroup = app.curSchedGroup;if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, Setting process group of + app.processName + to + app.curSchedGroup);if (app.waitingToKill != null && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { Slog.i(TAG, Killing + app.toShortString() + : + app.waitingToKill); EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,app.processName, app.setAdj, app.waitingToKill); // 3 调用killProcessQuiet杀死进程 Process.killProcessQuiet(app.pid); success = false;} else { if (true) { long ldId = Binder.clearCallingIdentity(); try { // 4调用setProcessGroup修改进程的调度组 Process.setProcessGroup(app.pid, app.curSchedGroup); } catch (Exception e) {Slog.w(TAG, Failed setting process group of + app.pid + to + app.curSchedGroup);e.printStackTrace(); } finally {Binder.restoreCallingIdentity(oldId); } } else { if (app.thread != null) {try { app.thread.setSchedulingGroup(app.curSchedGroup);} catch (RemoteException e) {} } }} } return success; }

函数updateOomAdjLocked,更新OOM adj的值,这一部分的主要工作有: 1.调用computeOomAdjLocked方法计算oom adj的值,这个函数比较复杂,通过一系列的运算,计算出oom adj的值 2.调用setOomAdj来修改进程的oom adj的值,这个函数就是向进程的/proc/

/oom_adj文件写入计算出来的oom adj值 3.调用killProcessQuiet杀死进程 4.调用setProcessGroup修改进程的调度组 这里主要看第三步killProcessQuiet,这个函数在Process.java文件中:

public static final void killProcessQuiet(int pid) { sendSignalQuiet(pid, SIGNAL_KILL); }调用了 sendSignalQuiet函数,这是一个native函数:

public static final native void sendSignalQuiet(int pid, int signal);对应的实现在android_util_Process.cpp文件中:

void android_os_Process_sendSignalQuiet(JNIEnv* env, jobject clazz, jint pid, jint sig){ if (pid > 0) { kill(pid, sig);//杀死进程 }}到此为止进程杀死了,这种方式是直接杀死进程的方式,同样android还提供了一个被动杀死进程的机制 Low Memory Killer机制

3 Low Memory Killer机制 这一机制的主要思想就是定义不同的oom adj级别,并为每一个级别指定最小剩余阈值,

当内存中可用内存小于该阈值时,就杀死所有等于或者大于该级别的进程,这部分参看 Low Memory Killer机制

篇5:Android中数据库升级

public class MySQLiteHelper extends SQLiteOpenHelper {public static final String SQL_CREATE= “create table news (” + “_id integer primary key autoincrement, ” + “nametext, ” + “agetext, )”; public MySQLiteHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version);} @Overridepublic void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE); } @Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {} }

当我们如上创建了个SQLiteHelper,我们知道会在本地的目录database中生成了个.db数据库文件! 可是我们遇到版本迭代往往要做更多的事情 这时候的会再创建个新的数据库

这时候我们编译完成之后发现没有在database相对应的目录下生成一个相对应的表,

Android中数据库升级

,当然我们在调试代码的时候可以清楚应用数据这样重新运行的时候会把onCreate方法再次执行一次那当然就会把未生成成功的表生成出来,可以在用户迭代更新应用的时候总不能每次都清楚数据是吧! 所以:

@Override“ int=”int“ name=”code“ newversion=”newVersion)“ oldversion=”oldVersion,“ oncreatedb=”onCreate(db);“ onupgradesqlitedatabase=”onUpgrade(SQLiteDatabase“ pre=”pre“ public=”public“ void=”void“>主要思路就是更新version,就是说你用户现有装的app上version是1的时候,在迭代版本更新的时候要更新version为>1的值 这样我们在new MySQLiteHelper 的时候就会执行onUpgrade()方法,然后在在该方法中写入相对应的操作就会在database下生产相对应的表而不需要用户去清除应用的数据。

当然这种方法有一个很严重的弊端就是 可能我们在发布版本的时候忘记修改该version导致无法操作数据引起一系列不可收拾的bug。 所以推荐使用LitePal开源库进行对数据库操作!详情可见 点击打开链接

篇6:Android中各种drawable的使用

其实这些个drawable的使用并不难,也不需要去哪里百度或者Google找答案,直接自己试验一下即可,

如:ic-launcher图标具体大小是多少,如有的人把一张512 x 512的图片当成ic-launcher,在高分辨率手机上没有问题,但是在一些低分辨率手机上发现桌面上找不到自己应用的图标,或者显示名称但看不到图标,想找ic-launcher标准大小吗?创建一个Android项目不就有了吗?看系统生成的那些ic-launcher在各种drawable上的大小即可,这就是最标准的了,何需百度,出图标的时候就让美工按着那些图标大小出就不会有问题了。

又如,通知栏图标要多大呢?如果大小不合适,则显示通知的时候看到的图标可能显示不全或者其它问题,要想知道通知栏图标多大合适,找Android系统设计的那些呀,路径为:sdkplatformsandroid-15data es,在这里搜索notification,然后看看相同名字的通知栏图标在不同的drawable中的大小是多少,这样你就知道你应该让美工给你切多大的通知栏图标了^_^

接下来了解本质的东西,下面的内容都是我拿真实手机测试出来的结果,所以应该比百度出来的那些更有真实性。

一般手机的分辨率对应的各参数为:

drawable-ldpi 文件夹: 低密度屏幕:dpi = 120dp,scale = ??, 超级元老,不用管它,不会再有这种dpi的手机的啦!drawable-mdpi 文件夹: 中等密度屏 幕:dpi = 160dp,scale = 1.0,分辨率:320 x 480drawable-hdpi 文件夹: 高密度屏幕:dpi = 240dp,scale = 1.5,分辨率:480 x 854drawable-xhdpi 文件夹: 超高密度屏幕:dpi = 320dp,scale = 2.0,分辨率:720 x 1280drawable-xxhdpi文件夹: 超超高密度屏幕:dpi = 480dp,scale= 3.0,分辨率:1080 x 1920

scale 为缩放系数,标准的dpi是160dpi,所以160dpi的scale为1.0,其它dpi的缩放系数都是与160相比算出来的,如320dpi,它除以160dpi结果为2,所以320dpi的scale为2.0

好,有了这个scale之后呢创建图片就简单了,怎么个简单法?先找出160dpi对应的大小就OK了,

如,美工设计了一张很美的图片,而且是以720 x 1080的分辨率为基础进行设计,假如宽高都为300像素,则这张图放在720 x1280的手机上显示肯定是完美的,如果放到其它分辨就有可能会被压缩或者放大,那效果就会大打折扣,所以我们大家都知道要切多套图片放到不同的drawable目录中,那问题来了,美工如果她不懂,她问你,其它分辨率怎么切图?

怎么切呢?我们就先算出160dpi对应的大小就行了,它切的图是以720 x 1080的手机为基础设计的,这个分辨率对应的是xhdpi,scale是2.0,所以160dpi对应的大小就是:300 / 2.0 = 150像素,那这样的话4种drawable的图片怎么切就有答案了:

160dpi 的图片大小为150像素,那其它的就按scale去算就好了,如下:drawable-hdpi: 150* 1.5 = 225drawable-xhdpi: 150 *2.0 = 300drawable-xxhdpi: 150 *3.0 = 450

就目前情况来说,切图切4套就够了。

假如,有一张图片,你并不知道它是在哪个分辨率的基础上进行设计的,那你就不知道这张图片应该放在哪个drawable文件夹中,这种情况经常会遇到,比如我们学习Android时的那些图片,根本不知道是谁设计的,也不知道是在哪个分辨率的基础上设计的,那你怎么知道放在哪个drawable文件夹中比较合适呢?一般人会选择放在drawable-hdpi 文件夹中,或许吧,多人这么做肯定是这样做一般没什么问题,但是,同一张图片,注:只有一张图片哦,把它放到不同的drawable文件夹中,然后在同一台手机上的显示效果会不一样哦,为什么会这样呢?嗯,夜已深,我先睡觉,有时间再来写完它。。。

篇7:Android中RemoteViews的实现

本文结合AppWidget的应用场景,分析Android中RemoteViews的内部具体实现,

从前文《Android中AppWidget的分析与应用:AppWidgetProvider》和《Android中Launcher对于AppWidget的处理的分析:AppWidgetHost角色》中得知,Android中AppWidget的图形资源是由AppWidgetProvider通过RemoteViews提供的;而显示是由AppWidgetHost通过AppWidgetHostView把RemoteView提供的内容显示在本地View上的。AppWidgetProvider和AppWidgetHostView运行在不同的程序中,而它们沟通的图形元素和点击回馈的桥梁就是RemoteViews。

下面为了行文方便和一致,把RemoteViews的内容提供方AppWidgetProvoder称作Remote端;而显示RemoteViews内容的一方AppWidgetHost称作Local端。

一、给RemoteViews提供内容——SettingsAppWidgetProvider

下图是SettingsAppWidgetProvider(位于Settings中的com.android.settings.widget包中)作为AppWidgetProvider得到update通知之后,创建RemoteViews,并把Remote端的响应Intent以及图形元素放进RemoteViews中的顺序图。

图一、为RemoteViews提供内容和侦听

图中,

1.       Settings创建RemoteViews时,把packageName和layoutId传进去并保存起来。packageName相当重要,因为这里的layoutId和各种其他资源都是相对这个程序来说的,只有通过packageName获得相应的Context,才能进而获得资源,否则其他程序是无法获得这些资源的[Seq#1]。

2.       Settings把layoutId中的viewId指示的View被点击之后获得响应的PendingIntent设置到RemoteViews中[Seq#2~ #5]。

RemoteViews创建SetOnClickPendingIntent并把id和intent传入,SetOnClickPendingIntent保存这些值;

SetOnClickPendingIntent是RemoteViews.Action的子类,通过addAction把SetOnClickPendingIntent加入到mActions:ArrayList保存下来。

3.       Settings把layoutId中的viewId指示的View的ImageSourceID设置到RemoteViews中[Seq#6~ #10]。

RemoteViews中有很多setXYZ()的方法,用来根据不同的要设置值的类型来设置;

setXYZ()创建ReflectionAction并把viewId和value,以及“setImageResource”作为methodName传入,ReflectionAction保存这些值;

ReflectionAction是RemoteViews.Action的子类,通过addAction()把ReflectionAction加入到mActions:ArrayList保存下来。

这里描述的是一个子过程,后续会通过AppWidgetManager把这个创建好的RemoteViews放进AppWidget系统中,从而使得AppWidget的AppWidgetHost端更新显示RemoteViews里承载的内容,

Remote端设置内容的过程,只是设置这些参数,而RemoteViews也只是用不同的RemoteViews.Action保存了这些参数。下文描述内部结构。

注意:这里的参数都是在Remote端的,在RemoteContext有效。

二、RemoteViews的内部结构

下图是RemoteViews相关的类图。

图二、RemoteViews类图

RemoteViews中保存Remote端的mPackage和mLayoutId;并用mActions:ArrayList保存各种Action。

mPackage和mLayoutId是在构造RemoteViews时传进去的[上文图中的seq#1];

mActions是设置各种Remote端的响应Intent以及图形元素的时候,保存到相应的Action中,然后把Action加入到这里保存的;

mLayoutId里的各种控件通过setTextViewText()/ setImageViewResource() / setProgressBar(),等函数在remote端设置的。这些方法再调用setType() [Type可为Boolean / Byte / Short / Int/ Long / Char / String / Uri / Bitmap/ Bundle, etc]保存到ReflectionAction中。

SetOnClickPendingIntent是用来在local端用户点击viewId时,发出pendingIntent通知的。在SetOnClickPendingIntent的构造方法中保存viewId和pendingIntent。

ReflectionAction用来在local端显示时,通过Reflect机制执行获得Remote端资源的。在ReflectionAction的构造方法中保存viewId,methodName,type以及value。

ViewGroupAction和SetDrawableParameters也是RemoteViews.Action的子类,在这个场景中并未用到,基本原理相似,读者可自行分析。

三、显示RemoteViews内容——AppWidgetHostView

图一中为RemoteViews提供了内容之后,AppWidgetHost会通过IAppWidgetHost.updateAppWidget()被通知到Remote端有更新,本地端把RemoteViews提供的内容显示在AppWidgetHostView上。下面的顺序图描述这一过程。

图三、本地显示RemoteViews里的内容

图中:

1.     获取RemoteViews里Remote端(AppWidgetProvider)的packageName和layoutId,通过packageName创建远端的context——remoteContext。[Seq#1~ 6]

2.     通过RemoteViews的apply()方法,真正开始执行侦听Click操作的动作;通过远端Layout获得本地使用的View。[Seq#7~ 20]

2.1. 克隆一个本地的LayoutInflater;[Seq#8]

2.2. 用克隆出的LayoutInflater对remote端的layoutId执行Inflate,获得Layout所描述的View的Hierarchy,亦即后面用到的rootView;[Seq#9~ 10]

2.3. 对2.2中获得的view执行performApply。[Seq#11~ 19]

performApply()对所有mActions中的Action都执行apply()操作。这样,

篇8:如何删除android中的一些程序

此操作有可能会对系统产生影响,建议先进行备份后再操作,

前提条件:

1、操作系统建议为Windows XP、32位Windows Vista、32位Windows 7

2、USB数据线、Desire电量高于30%、电脑系统能正确识别Desire

3、Android SDK(2.1版本下载 / 2.2版本下载)

4、良好的心理素质以及动手能力

5、已取得root权限

6、rooting文件包(立即下载)

具体操作方法如下:

1、手机连接USB线后,用音量键”下“+电源键开机,出现红色叹号后,运行rooting包的recovery-windows.bat进入绿色recovery界面(不要关闭cmd窗口)

2、另开一个cmd窗口,进入rooting文件所在目录,装载/system目录

操作代码:

adb-windows shell mount /system

3、显示系统已安装的程序

操作代码:

adb-windows shell ls /system/app/

显示结果如下:

AccountAndSyncSettings.apk

ApplicationsProvider.apk

Bluetooth.apk

...........

HtcStreamPlayer.apk

htcsettingwidgets.apk

HtcSyncwidget.apk

HtcTwitter.apk

...........

4、有两种移除程序的方式:彻底删除或者移到SD卡上

A、彻底删除,

举例,操作代码:

adb-windows shell rm /system/app/Stock.apk

adb-windows shell rm /system/app/com.htc.StockWidget.apk

B、移到SD卡的某个目录下。

举例,操作代码:

adb-windows shell mkdir /sdcard/device_files (注释:这行代码是创建文件夹)

adb-windows mv /system/app/Stock.apk /sdcard/device-files

adb-windows mv /system/app/com.htc.StockWidget.apk /sdcard/device-files

5、至此,删除”无用“app工作结束。重启手机。

篇9:策略模式在android中使用

策略模式(Strategy)

策略模式是对象的行为模式,它的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不修改或影响到调用端的情况下发生变化。

下面来讨论下策略模式的结构类图,具体如下:

从上面的结构图中,我们可以看出策略模式涉及到了三个角色,具体角色如下所示:

A、抽象策略角色:这是个抽象角色,通常是由一个接口或是抽象类来实现。它为所有的具体策略类提供了需要的接口。

B、具体策略角色:这个角色包装了相关的算法和行为,用来执行对应的策略事件。

C、环境角色:这个角色中含有一个对抽象策略类的引用,也是供外部调用直接接触的角色。

下面具体举个例子来使用策略模式。例子是这样的:现在要做一个上网使用得app,接入的网络类型有三种,分别为CMCC、ChinaNet及普通的Wifi类型,所以针对这几种类型的网络,我们需要定义一个抽象的策略角色,然后再定义三个具体角色,每个具体的角色中实现具体的功能细节,最后,我们在前端放置三个按钮,点击对应的按钮调用对应的具体角色逻辑(通过调用抽象角色)。下面为我的代码逻辑实现以及部分说明文字:

抽象策略角色(WifiConnectStrategy):

/**

* 抽象策略角色

*/

public abstract classWifiConnectStrategyimplementsCallback{

privateWifiConnectStrategyListener listener =null;

protectedWifiState wifiState =null;

protectedHandler handler =null;

protected static final longCONN_WIFI_TIME= ; // 连接wifi的时间(模拟)

publicWifiConnectStrategy {

handler =newHandler(WifiConnectStrategy.this);

}

public voidsetWifiConnectStrategyListener(WifiConnectStrategyListener listener) {

this.listener = listener;

}

/**

* 创建一个策略,根据wifitype

*/

public staticWifiConnectStrategycreateWithWifiType(WifiType wifiType) {

WifiConnectStrategy result =null;

switch(wifiType) {

caseCMCC:

result =newCMCCWifiConnectStrategy();

break;

caseCHINANET:

result =newChinaNetWifiConnectStrategy();

break;

caseCOMMON:

result =newCommonWifiConnectStrategy();

break;

default:

break;

}

returnresult;

}

public voidconfigWifiState(WifiState wifiState) {

this.wifiState = wifiState;

}

/**

* 连接到网络的方法

*/

public abstract voidexecuteConnectNetRun();

/**

* 模拟链接后返回的结果

*/

public abstract voidconnectResult();

// 模拟网络链接延迟

protected voidsimulateConnect() {

this.handler.removeMessages(1);

this.handler.sendEmptyMessageDelayed(1,CONN_WIFI_TIME);

}

@Override

public booleanhandleMessage(Message msg) {

connectResult();

return true;

}

publicWifiConnectStrategyListener getListener() {

returnlistener;

}

public voidsetListener(WifiConnectStrategyListener listener) {

this.listener = listener;

}

public voidlog(String log) {

Log.d(WifiConnectStrategy, log);

}

}

具体策略角色(CMCC):

/**

* 具体策略角色

*/

public classCMCCWifiConnectStrategyextendsWifiConnectStrategy {

publicCMCCWifiConnectStrategy() {

super();

}

@Override

public voidexecuteConnectNetRun() {

log(cmcc connect ...);

// 链接网络核心代码(异步)

//TODO

// 模拟网络链接延迟

simulateConnect();

}

@Override

public voidconnectResult(){

getListener().cmccConnResult(this.wifiState.getWifiLabel() +连接成功!);

}

}

具体策略角色(ChinaNet):

public classChinaNetWifiConnectStrategyextendsWifiConnectStrategy {

publicChinaNetWifiConnectStrategy() {

super();

}

@Override

public voidexecuteConnectNetRun() {

log(chinanet connect ...);

// 链接网络核心代码

//TODO

// 模拟网络链接延迟

simulateConnect();

}

@Override

public voidconnectResult(){

getListener().cmccConnResult(this.wifiState.getWifiLabel() +连接成功!);

}

}

具体策略角色(Common wifi):

public classCommonWifiConnectStrategyextendsWifiConnectStrategy {

publicCommonWifiConnectStrategy() {

super();

}

@Override

public voidexecuteConnectNetRun(){

log(common connect ...);

// 链接网络核心代码

//TODO

// 模拟网络链接延迟

simulateConnect();

}

@Override

public voidconnectResult(){

getListener().cmccConnResult(this.wifiState.getWifiLabel() +连接成功!);

}

}

下面为我们具体的环境角色,主要就是引用一个抽象策略角色,以及根据不同网络类型创建对应的具体策略角色,具体如下:

public classMainActivityextendsActivityimplementsOnClickListener {

privateButton btnCmcc =null;

privateButton btnChinanet =null;

privateButton btnCommon =null;

privateWifiConnectStrategy wifiConnectStrategy;

privateWifiState selectedState =newWifiState();

privateWifiConnectStrategyListener listener =newWifiConnectStrategyListener() {

@Override

public voidcmccConnResult(String state) {

log(state);

}

@Override

public voidchinanetConnResult(Stringstate) {

log(state);

}

@Override

public voidcommonConnResult(String state) {

log(state);

}

};

@Override

protected voidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btnCmcc = (Button) findViewById(R.id.btnCmcc);

btnChinanet = (Button) findViewById(R.id.btnChinanet);

btnCommon = (Button) findViewById(R.id.btnCommon);

btnCmcc.setOnClickListener(this);

btnChinanet.setOnClickListener(this);

btnCommon.setOnClickListener(this);

}

@Override

public voidonClick(View v) {

if(null!= wifiConnectStrategy) {

wifiConnectStrategy =null;

}

if(v.getId() == R.id.btnCmcc) {

selectedState.setCardNo(cmcc+1167278922);

selectedState.setIpAddress(192168013);

selectedState.setPassword(123456);

selectedState.setWifiLabel(CMCC);

selectedState.setSsid(dafadfdadada);

selectedState.setWifiType(WifiType.CMCC);

wifiConnSpecial(selectedState);

}

else if(v.getId() == R.id.btnChinanet) {

selectedState.setCardNo(cmcc+1167272222);

selectedState.setIpAddress(192168433);

selectedState.setPassword(123456777);

selectedState.setWifiLabel(ChinaNet);

selectedState.setSsid(dafadeeeedada);

selectedState.setWifiType(WifiType.CHINANET);

wifiConnSpecial(selectedState);

}

else{

selectedState.setIpAddress(192168111);

selectedState.setPassword(123456789);

selectedState.setWifiLabel(COMMON);

selectedState.setSsid(dafadeeeSSDASF);

selectedState.setWifiType(WifiType.COMMON);

wifiConnCommon(selectedState);

}

}

private voidwifiConnSpecial(WifiState wifiState) {

wifiConnectStrategy = WifiConnectStrategy.createWithWifiType(selectedState.getWifiType());

wifiConnectStrategy.configWifiState(wifiState);

wifiConnectStrategy.setWifiConnectStrategyListener(listener);

wifiConnectStrategy.executeConnectNetRun();

}

private voidwifiConnCommon(WifiState wifiState) {

wifiConnectStrategy = WifiConnectStrategy.createWithWifiType(selectedState.getWifiType());

wifiConnectStrategy.configWifiState(wifiState);

wifiConnectStrategy.setWifiConnectStrategyListener(listener);

wifiConnectStrategy.executeConnectNetRun();

}

private voidlog(String log) {

Log.d(WifiConnectStrategy,log);

}

}

注意:这里的WifiState类为wifi的封装类,WifiConnectStrategyListener为监听网络链接的接口,

接下来,我会在下面罗列出他们的代码构成。

WifiState:

public classWifiState {

//wifiname

privateString wifiLabel;

//wifi ip

private intipAddress;

//wifi ssid

privateString ssid;

//wifipassword

privateString password;

// card no

privateString cardNo;

// 类型

privateWifiType wifiType;

//wifi类型

public enumWifiType {

CMCC(1),

CHINANET(2),

COMMON(3);

private final inttype;

privateWifiType(inttype) {

this.type = type;

}

public intgetType() {

returntype;

}

public staticWifiTypegetType(intwifiType) {

WifiTypetype =null;

if(WifiType.CMCC.getType() == wifiType) {

type = WifiType.CMCC;

}

else if(WifiType.CHINANET.getType() == wifiType) {

type = WifiType.CHINANET;

}

else if(WifiType.COMMON.getType() == wifiType) {

type = WifiType.COMMON;

}

returntype;

}

}

public intgetIpAddress() {

returnipAddress;

}

public voidsetIpAddress(intipAddress) {

this.ipAddress = ipAddress;

}

publicString getSsid() {

returnssid;

}

public voidsetSsid(String ssid) {

this.ssid = ssid;

}

publicString getPassword() {

returnpassword;

}

public voidsetPassword(String password) {

this.password = password;

}

publicString getCardNo() {

returncardNo;

}

public voidsetCardNo(StringcardNo) {

this.cardNo = cardNo;

}

publicString getWifiLabel() {

returnwifiLabel;

}

public voidsetWifiLabel(String wifiLabel) {

this.wifiLabel = wifiLabel;

}

publicWifiType getWifiType() {

returnwifiType;

}

public voidsetWifiType(WifiType wifiType) {

this.wifiType = wifiType;

}

}

WifiConnectStrategyListener:

/**

*wifi链接的监听

*/

public interfaceWifiConnectStrategyListener {

public voidcmccConnResult(String state);

public voidchinanetConnResult(String state);

public voidcommonConnResult(String state);

}

好了,运行下代码,页面效果如下:

当我们点击对应的按钮链接网络时,会在输出日志打印对应的wifi链接以及链接成功,当然,这是只是模拟实现,实际上整个过程没这么简单,比如需要先获得卡号,然后异步链接,获得返回的信息,链接是否成功等。

日志如下:

好了,到这里,策略模式的介绍就完成了,稍后会把项目代码上传,希望对大家有帮助。

篇10:Android中对日期进行排序

最近在项目中需要将读取的数据按照时间的降序进行排序,

具体的步骤如下:

1.读取数据,存入List中

2.取出数据中的时间戳,由String转换成Date

3.使用冒泡排序对List中元素按照Date进行排序

具体代码如下:

//将List按照时间倒序排列 @SuppressLint(SimpleDateFormat) private ListinvertOrderList(ListL){ SimpleDateFormat sdf = new SimpleDateFormat(yyyy-MM-dd HH:mm:ss); Date d1; Date d2; TestEntity temp_r = new TestEntity(); //做一个冒泡排序,大的在数组的前列 for(int i=0; i

《江南Style》主持词

android学习方法

android面试题

侃侃Style风作文

青春Style成长日记

学习方式(learning style)

Android工程师面试题

android实习总结报告

Android笔试题

Android中创建倒影效果的工具类

Android中的Theme和Style(集锦10篇)

欢迎下载DOC格式的Android中的Theme和Style,但愿能给您带来参考作用!
推荐度: 推荐 推荐 推荐 推荐 推荐
点击下载文档 文档为doc格式
点击下载本文文档