首页 文章 精选 留言 我的

精选列表

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

Android开发之旅:组件生命周期(一)

引言 应用程序组件有一个生命周期——一开始Android实例化他们响应意图,直到结束实例被销毁。在这期间,他们有时候处于激活状态,有时候处于非激活状态;对于活动,对用户有时候可见,有时候不可见。组件生命周期将讨论活动、服务、广播接收者的生命周期——包括在生命周期中他们可能的状态、通知状态改变的方法、及这些状态的组件寄宿的进程被终结和实例被销毁的可能性。 本文主要讨论活动的生命周期及他们可能的状态、通知状态改变的方法。分为以下三部分: 1、活动生命周期 2、保存活动状态 3、协调活动 1、活动生命周期 一个活动有三个基本状态: 激活状态或运行状态,这时它运行在屏幕的前台(处于当前任务活动栈的最上面)。这个活动有用户的操作的焦点。 暂停状态,这时活动失去焦点但是它对用户仍可见。也就是说,另一个活动在它的上面且那个活动是透明的或者没有覆盖整个屏幕,因此通过它可以看见暂停状态的活动。一个暂停的活动完全是活着的(它维护着所有的状态和成员信息,且仍然依附在窗口管理器),但是当内存极小时可以被系统杀掉。 停止状态,这时活动完全被其他活动掩盖。它仍然保留所有状态和成员信息,但是对用户它不可见,因此它的窗口时隐藏的且当其他地方需要内存时它往往被系统杀掉。 如果一个活动被暂停或停止,系统可以将它从内存移除,通过要求它结束(通过调用它的finish()方法),或简单地杀掉它的进程。当它再次显示给用户时,必须要完全重新启动和恢复到之前的状态。随着活动从一个状态转为另一个状态,通过调用下面的受保护的方法通知该改变: void onCreate(BundlesaveInstanceState) void onStart() void onRestart() void onResume() void onPause() void onStop() void onDestroy() 所有这些方法都是钩子,你可以重写当状态改变时做适当的工作。所有的活动必须要实现onCreate()去做一些初始化的设置,当对象第一次实例化的时候。很多活动也会实现onPause()去提交数据修改或准备停止与用户交互。 将他们合并在一起,这七个方法定义了活动的整个生命周期。有三个嵌套的循环,你可以通过这七个方法监视: 活动的整个生命时间,从第一次调用onCreate()开始直到调用onDestroy()结束。一个活动在onCreate()中做所有的“全局”状态的初始设置,在onDestroy()中释放所有保留的资源。举例来说,有一个线程运行在后台从网络上下载数据,它可能会在onCreate()中创建线程,在onDestroy()中结束线程。 活动的可视生命时间,从调用onStart()到相应的调用onStop()。在这期间,用户可以在屏幕上看见活动,虽然它可能不是运行在前台且与用户交互。在这两个方法之间,你可以保持显示活动所需要的资源。举例来说,你可以在onStart()中注册一个广播接收者监视影响你的UI的改变,在onStop()中注销。因为活动在可视和隐藏之间来回切换,onStart()和onStop()可以调用多次。 活动的前台生命时间,从调用onResume()到相应的调用onPause()。在这期间,频繁地在重用和暂停状态转换——例如,当设备进入睡眠状态或一个新的活动启动时调用onPause(),当一个活动返回或一个新的意图被传输时调用onResume()。因此,这两个方法的代码应当是相当轻量级的。 下面这个图解释了这三个循环和状态之间状态的可能路径。着色的椭圆表示活动的主要状态,矩形表示当活动在状态之间转换时你可以执行的回调方法。 图1、活动生命周期(来源:Android SDK) 下面的表格对每个方法更详细的描述和在活动的整个生命周期中的定位。 注意上面表格的Killable列,它表示当方法返回时没有执行活动的其它代码,系统是否能杀死活动寄宿的进程。三个方法(onPause()、onStop()、onDestroy())标记为Yes。因为onPause()是唯一一个保证在进程被杀之前会调用的,因此你应该使用onPause()来写任何持久化存储数据。 被标记为No的方法保护活动寄宿的进程在他们调用的时候不会被杀掉。因此活动是可杀掉状态,例如onPause()返回到onResume()调用期间。直到onPause()再次返回,活动是不可杀掉的。其实,没有标记为Killable的活动也是可以系统被杀掉的,不过这仅仅发生在极端困难的情况下,没有有任何其他资源可用。 2、保存活动状态 当系统而不是用户关闭一个活动来节省内存时,用户可能希望返回到活动且是它之前的状态。为了获得活动被杀之前的状态,你可以执行活动的onSaveInstanceState()方法。Android在活动容易被销毁前调用这个方法,也就是调用onPause()之前。该方法的参数是一个Bundle对象,在这个对象你可以以名值对记录活动的动态状态。当活动再次启动时,Bundle同时被传递到onCreate()和调用onCreate()之后的方法,onRestoreInstanceState(),因此使用一个或两个可以重新创建捕获的状态。 因为onSaveInstanceState()方法不总是被调用,你应该仅使用onSaveInstanceState()它来记录活动的临时状态,而不是持久的数据。应该使用onPause()来存储持久数据。 3、协调活动 当一个活动启动另一个活动,他们都经历生命周期转换。一个暂停或许是停止,然而另一个启动。有时,你可能需要协调这些活动。生命周期的回调顺序是明确界定的,特别是当这两个活动在同一个进程中: 当前活动的onPause()方法被调用。 接下来,启动活动的onCreate()、onStart()、onResume()方法按序被调用。 然后,如果获得不再在屏幕上可见,它的onStop()方法被调用。 修正:第一节——活动生命周期中的表格第一、二行中的第二列(description)中的onRestart()应该为onStart()。 1000多的点击,居然没有人发现这个错误,看了大家根本就没认真看或者说根本没有静心看园子里的任何博文,心痛!还是水帖比较受欢迎。 本文转自Saylor87 51CTO博客,原文链接:http://blog.51cto.com/skynet/365375,如需转载请自行联系原作者

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

iOS开发-自定义UIAlterView(iOS 7)

App中不可能少了弹框,弹框是交互的必要形式,使用起来也非常简单,不过最近需要自定义一个弹框,虽然iOS本身的弹框已经能满足大部分的需求,但是不可避免还是需要做一些自定义的工作。iOS7之前是可以自定义AlterView的,就是继承一下UIAlterView,然后初始化的时候通过addSubview添加自定义的View,但是iOS7之后这样做就不行了,不过还好有开源项目可以解决这个问题。 iOS默认弹框 viewDidLoad中添加两个按钮,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 UIButton *orignalBtn=[[UIButton alloc]initWithFrame:CGRectMake(100, 40, 100, 50)]; [orignalBtn setBackgroundColor:[UIColor greenColor]]; [orignalBtn setTitle:@ "iOS弹框" forState:UIControlStateNormal]; [orignalBtn addTarget: self action: @selector (orignalShow) forControlEvents:UIControlEventTouchUpInside]; [ self .view addSubview:orignalBtn]; UIButton *customlBtn=[[UIButton alloc]initWithFrame:CGRectMake(100, 140, 100, 50)]; [customlBtn setBackgroundColor:[UIColor redColor]]; [customlBtn setTitle:@ "自定义弹框" forState:UIControlStateNormal]; [customlBtn addTarget: self action: @selector (customShow) forControlEvents:UIControlEventTouchUpInside]; [ self .view addSubview:customlBtn]; 响应默认弹框事件: 1 2 3 4 -( void )orignalShow{ UIAlertView *alterView=[[UIAlertView alloc]initWithTitle:@ "提示" message:@ "博客园-Fly_Elephant" delegate: self cancelButtonTitle:@ "取消" otherButtonTitles:@ "确定" , nil ]; [alterView show]; } 效果如下: 自定义弹框 主要解决iOS7之后的系统无法自定义弹框的问题,使用开源项目,项目地址:https://github.com/wimagguc/ios-custom-alertview,其实就是自定义了一个类: CustomIOSAlertView.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #import <UIKit/UIKit.h> @protocol CustomIOSAlertViewDelegate - ( void )customIOS7dialogButtonTouchUpInside:( id )alertView clickedButtonAtIndex:( NSInteger )buttonIndex; @end @interface CustomIOSAlertView : UIView<CustomIOSAlertViewDelegate> @property ( nonatomic , retain) UIView *parentView; // The parent view this 'dialog' is attached to @property ( nonatomic , retain) UIView *dialogView; // Dialog's container view @property ( nonatomic , retain) UIView *containerView; // Container within the dialog (place your ui elements here) @property ( nonatomic , assign) id <CustomIOSAlertViewDelegate> delegate; @property ( nonatomic , retain) NSArray *buttonTitles; @property ( nonatomic , assign) BOOL useMotionEffects; @property ( copy ) void (^onButtonTouchUpInside)(CustomIOSAlertView *alertView, int buttonIndex) ; - ( id )init; /*! DEPRECATED: Use the [CustomIOSAlertView init] method without passing a parent view. */ - ( id )initWithParentView: (UIView *)_parentView __attribute__ (( deprecated )); - ( void )show; - ( void )close; - ( IBAction )customIOS7dialogButtonTouchUpInside:( id )sender; - ( void )setOnButtonTouchUpInside:( void (^)(CustomIOSAlertView *alertView, int buttonIndex))onButtonTouchUpInside; - ( void )deviceOrientationDidChange: ( NSNotification *)notification; - ( void )dealloc; @end CustomIOSAlertView.m + View Code 调用代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 -( void )customShow{ CustomIOSAlertView *alertView = [[CustomIOSAlertView alloc] init]; [alertView setContainerView:[ self customView]]; [alertView setButtonTitles:[ NSMutableArray arrayWithObjects:@ "取消" , @ "确定" , nil ]]; [alertView setDelegate: self ]; [alertView setOnButtonTouchUpInside:^(CustomIOSAlertView *alertView, int buttonIndex) { NSString *result=alertView.buttonTitles[buttonIndex]; NSLog (@ "点击了%@按钮" ,result); [alertView close]; }]; [alertView setUseMotionEffects: true ]; [alertView show]; } - (UIView *)customView { UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 240, 160)]; UILabel *tip=[[UILabel alloc]initWithFrame:CGRectMake(100, 10, 50, 30)]; [tip setText:@ "提示" ]; [customView addSubview:tip]; UILabel *content=[[UILabel alloc]initWithFrame:CGRectMake(10, 60, 210, 30)]; [content setText:@ "http://www.cnblogs.com/xiaofeixiang" ]; [content setFont:[UIFont systemFontOfSize:12]]; [customView addSubview:content]; return customView; } 效果如下: 本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4453819.html,如需转载请自行联系原作者

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

Android开发学习笔记:EditText的属性介绍

EditText继承TextView,所以EditText具有TextView的属性特点,下面主要介绍一些EditText的特有的输入法的属性特点 android:layout_gravity="center_vertical":设置控件显示的位置:默认top,这里居中显示,还有bottom android:hin :Text为空时显示的文字提示信息,可通过textColorHint设置提示信息的颜色。 android:singleLine :设置单行输入,一旦设置为 true ,则文字不会自动换行。 android:gray="top" :多行中指针在第一行第一位置 et.setSelection(et.length()); :调整光标到最后一行 android:autoText :自动拼写帮助。这里单独设置是没有效果的,可能需要其他输入法辅助才行 android:capitalize :设置英文字母大写类型。设置如下值:sentences仅第一个字母大写;words每一个单词首字母大小,用空格区分单词;characters每一个英文字母都大写。 android:digits :设置允许输入哪些字符。如“1234567890.+-*/%\n()” android:singleLine :是否单行或者多行,回车是离开文本框还是文本框增加新行 android:numeric :如果被设置,该TextView接收数字输入。有如下值设置:integer正整数、signed带符号整数、decimal带小数点浮点数。 android:inputType:设置文本的类型 android:password :密码,以小点”.”显示文本 android:phoneNumber :设置为电话号码的输入方式。 android:editable :设置是否可编辑。仍然可以获取光标,但是无法输入。 android:autoLink=”all” :设置文本超链接样式当点击网址时,跳向该网址 android:textColor = "#ff8c00" :字体颜色 android:textStyle="bold" :字体, bold, italic, bolditalic android:textAlign="center" : EditText 没有这个属性,但 TextView 有 android:textColorHighlight="#cccccc" :被选中文字的底色,默认为蓝色 android:textColorHint="#ffff00" :设置提示信息文字的颜色,默认为灰色 android:textScaleX="1.5" :控制字与字之间的间距 android:typeface="monospace" :字型, normal, sans, serif, monospace android:background="@null" :空间背景,这里没有,指透明 android:layout_weight="1" :权重在控制控件显示的大小时蛮有用的。 android:textAppearance="?android:attr/textAppearanceLargeInverse" :文字外观,这里引用的是系统自带的一个外观,?表示系统是否有这种外观,否则使用默认的外观。 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/627350

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

Android开发学习笔记:对话框浅析

对话框式程序运行中弹出的窗口。Android系统中有四种默认的对话框:警告对话框AlertDialog、进度对话框ProgressDialog、日期选择对话框DatePickerDialog以及时间选择对话框TimePickerDialog。除此之外,我们自定义自已的dialog。 一.警告对话框(AlertDialog) Android系统中最常用的对话框是AlertDialog,它是一个提示窗口,需要用户作出选择的。一般会有几个按钮、标题信息、提示信息等。 在程序中创建AlertDialog的步骤: 1.获得AlertDialog的静态内部类Builder对象,由该类来创建对话框,Builder所提供的方法如下: setTitle():给对话框设置title. setIcon():给对话框设置图标。 setMessage():设置对话框的提示信息 setItems():设置对话框要显示的一个list,一般用于要显示几个命令时 setSingleChoiceItems():设置对话框显示一个单选的List setMultiChoiceItems():用来设置对话框显示一系列的复选框。 setPositiveButton():给对话框添加”Yes”按钮。 setNegativeButton():给对话框添加”No”按钮。 2.调用Builder的create( )方法 3.调用AlertDialog的show( )方法显示对话框 下面是一个提示信息对话框的实例: AlertDialogActivity.java package com.android.dialog.activity; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class AlertDialogActivity extends Activity { private TextView tv; private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv = (TextView)findViewById(R.id.TextView_1); btn = (Button)findViewById(R.id.Button_1); //实例化AlertDialog.Builder对象 final AlertDialog.Builder builder = new AlertDialog.Builder(this); btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { //设置提示信息,确定按钮 builder.setMessage("真的要删除该文件吗?").setPositiveButton("是", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { tv.setText("成功删除"); } //设置取消按钮 }).setNegativeButton("否", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { tv.setText("取消删除"); } }); //创建对话框 AlertDialog ad = builder.create(); //显示对话框 ad.show(); } } ); } } main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/TextView_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试AlertDialog" /> <Button android:id="@+id/Button_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="删除文件" /> </LinearLayout> 效果图: 二.进度对话框(ProgressDialog) 在程序中创建ProgressDialog的步骤: 1.覆盖Activity的onCreateDialog( )方法,并在其中创建对话框 2.调用Activity的showDialog( )方法,显示进度对话框 下面是一个提示进度对话框的实例: ProgressDialogActivity.java packagecom.android.progress.activity; importandroid.app.Activity; importandroid.app.Dialog; importandroid.app.ProgressDialog; importandroid.content.DialogInterface; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassProgressDialogActivityextendsActivity{ privateButtonbtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button)findViewById(R.id.Button_1); btn.setOnClickListener(newOnClickListener(){ publicvoidonClick(Viewv){ //调用Activity的showDialog()方法,显示进度对话框 showDialog(0); } }); } @Override protectedDialogonCreateDialog(intid){ //对进度对话框进行实例化 ProgressDialogdialog=newProgressDialog(this); //设置显示的标题 dialog.setTitle("测试ProgressDialog"); dialog.setIndeterminate(true); dialog.setMessage("程序正在Loading..."); dialog.setCancelable(true); dialog.setButton(Dialog.BUTTON_POSITIVE,"确定", newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ dialog.cancel(); } } ); returndialog; } } main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/Button_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试ProgressDialog" /> </LinearLayout> 效果图: 三.日期,时间选择对话框(DatePickerDialog、TimePickerDialog) 在程序中创建日期,时间选择对话框的步骤: 1.覆盖Activity的onCreateDialog( )方法,并在其中创建对话框 2.分别在OnDateSetListener的onDateSet( )方法和OnTimeSetListener( )的onTimeSet( )事件方法中更改日期,时间 3.调用Activity的showDialog( )方法,显示进度对话框 MainActivity.java packagecom.android.datatime.activity; importjava.util.Calendar; importandroid.app.Activity; importandroid.app.DatePickerDialog; importandroid.app.Dialog; importandroid.app.TimePickerDialog; importandroid.app.DatePickerDialog.OnDateSetListener; importandroid.app.TimePickerDialog.OnTimeSetListener; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.DatePicker; importandroid.widget.TextView; importandroid.widget.TimePicker; publicclassMainActivityextendsActivity{ privateButtonbtn1,btn2; privateTextViewtv_1,tv_2; privateCalendarc;//获得日历实例 privateintm_year,m_month,m_day; privateintm_hour,m_minute; publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn1=(Button)findViewById(R.id.Button_1); btn2=(Button)findViewById(R.id.Button_2); c=Calendar.getInstance(); m_year=c.get(Calendar.YEAR); m_month=c.get(Calendar.MONTH); m_day=c.get(Calendar.DAY_OF_MONTH); m_hour=c.get(Calendar.HOUR); m_minute=c.get(Calendar.MINUTE); tv_1=(TextView)findViewById(R.id.TextView_1); tv_1.setText(m_year+":"+(m_month+1)+":"+m_day);//设置TextView里的内容为日期 tv_2=(TextView)findViewById(R.id.TextView_2); tv_2.setText(m_hour+":"+m_minute);//设置TextView里的内容为时间 btn1.setOnClickListener(newOnClickListener(){ publicvoidonClick(Viewv){ showDialog(0);//显示日期对话框 } }); btn2.setOnClickListener(newOnClickListener(){ publicvoidonClick(Viewv){ showDialog(1);//显示时间对话框 } }); } //调用Activity的showDialog()方法显示进对话框 protectedDialogonCreateDialog(intid){ if(id==0) returnnewDatePickerDialog(this,l1,m_year,m_month,m_day); else returnnewTimePickerDialog(this,l2,m_hour,m_minute,false); } //设置日期监听器 privateOnDateSetListenerl1=newOnDateSetListener(){ publicvoidonDateSet(DatePickerview,intyear,intmonthOfYear, intdayOfMonth){ m_year=year; m_month=monthOfYear; m_day=dayOfMonth; tv_1.setText(m_year+":"+(m_month+1)+":"+m_day);//为TextView设置文本内容,重新显示日期 } }; //设置时间监听器 privateOnTimeSetListenerl2=newOnTimeSetListener(){ publicvoidonTimeSet(TimePickerview,inthourOfDay,intminute){ m_hour=hourOfDay; m_minute=minute; tv_2.setText(m_hour+":"+m_minute);//为TextView设置文本内容,重新显示时间 } }; } main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:text="" android:id="@+id/TextView_1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:text="" android:id="@+id/TextView_2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:text="修改日期" android:id="@+id/Button_1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:text="修改时间" android:id="@+id/Button_2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/641365

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

Android开发学习笔记:反编译APK文件

反编译的目的在于学习一些优秀的Android应用程序代码。 在进行反编译之前,需要准备好下面的软件工具(这些文件都放在同一文件下): 这些工具的下载地址:http://down.51cto.com/data/266751 下面开始进行反编译APK文件: 1.先将上面的apktool-install-windows-2.1_r01-1.zip,dex2jar-0.0.7-SNAPSHOT.zip解压到一个盘的根目录的一个文件下面(这里我选择D:\APKTool) 2.Win+R打开运行界面,输入cmd,进入dos窗口,输入cd /d D:\APKTool进入到D:\APKTool下面,然后输入下面的命令,按Enter键,会出现下图所示 apktool.jar是解包工具,d表示解包,android.apk是要解包的APK文件,红色矩形框表示解包后输出到这个文件夹。这时候打开d:\AndroidCode,就能看到通过解包得到的文件 里面的AndroidManifest.xml文件和res下面的所有文件就能直接打开查看了。 3.解包之后,将之前的android.apk文件的后缀名改为rar,之后就将里面的classes.dex文件解压到D:\APKTool下面。然后在dos窗口输入dex2jar.bat classes.dex 得到一个名为classes.dex.dex2jar.jar的文件,此时用jd-gui.exe打开classes.dex.dex2jar.jar或者用DJ Java Decompiler反编译工具将.class文件反编译成.java文件就能看到所有源代码了! PS:APK文件反编译之后,XML的源码不会出现乱码,不过有些APK文件得到Java源码会出一些乱码(比如在给变量赋值的时候),我现在没有到更好的解决方法,如果大家有的话,可以给我发邮件的。 邮件地址:lingdududu@163.com 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/690370

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

使用天天模拟器开发Android应用

下载天天模拟器 天天模拟器官网 配置ADB环境变量 新建系统环境变量"ANDROID"内容为: D:\BACKUP\Android\adt-bundle-windows-x86_64-20140321\sdk\platform-tools; D:\BACKUP\Android\adt-bundle-windows-x86_64-20140321\sdk\; 编辑系统"Path",添加内容: %ANDROID%; 测试ADB命令 启动天天模拟器 运行ADB命令连接模拟器 2 、cd C:\Users\Free\AppData\Local\Android\sdk\platform-tools 3、adb connect 127.0.0.1:6555 参考:http://www.cnblogs.com/yilongm/p/5026021.html 本文转自yunlielai51CTO博客,原文链接:http://blog.51cto.com/4925054/1944675,如需转载请自行联系原作者

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

IOS开发需要知道的知识-RunLoops

什么是Run Loops Run Loops是与线程想关联的基础部分。一个Run Loop就是事件处理循环,它是用来调度和协调接收到的事件处理。使用Run Loop的目的,就是使得线程有工作需要做时可以忙碌起来,而当没有事可做时,又可以使得线程睡眠。 Run Loop管理不都是自动的。我们必须手动设计线程代码,在合适的时候来启动Run Loop,并回应到来的事件。Cocoa和Core Foundation都提供了run loop对象来帮助我们配置和管理线程的run loop。我们的应用没有必要显式地创建这些对象;每个线程,包括应用程序的主线程,都有一个与之关联的run loop。只有子线程才需要显式地运行其run loop。App会将自动配置和来运行主线程的run loop的任务作为应用程序启动处理的一部分。 对于想要更深入地了解Run Loop Objects,阅读NSRunLoop Class Reference、CFRunLoop Reference 一个Run Loop的结构 Run Loop就像它的名字一样,它使得线程进入事件循环,能对到来的事件启动事件处理。你的代码中提供了流程控制说一句来实现run loop实实在在的循环部分,换句话说,你的代码提供了while或者for循环来驱动run loop。在你的循环中,你使用run loop对象在事件到达时,运行事件处理的代码并调起已安装的处理程序。Run Loop接收来自两种不同类型的源(sources)的事件: 输入源:异步传递事件,通常是来自不同的线程或不同的应用的消息。输入源异步传递事件到对应的处理程序和在线程关联的NSRunLoop对象调起runUntilDate:方法来退出事件处理。 Timer源:同步地传递事件,发生在每个定时器调用或周期性地调用。Timer源传递事件到他们的处理程序,但是不会调用run loop来退出处理。 这两种源在事件到达时都使用应用程序特定的处理程序来处理事件。 如下图所示,展示了run loop和不同的源的概述结构。 image 除了处理输入源之外,run loops还发出关于run loop行为的通知。我们可以注册成为run loop的观察者,就可以接收这些通知和使用它在线程上做一些额外处理。我们可以使用Core Foundation在对应的线程上注册成为run loop的观察者。 Run Loop Modes Run Loop模式是一个监视输入源和定时器的集合和注册成为run loop的观察者的集合。每次要运行run loop,都需要显示或隐式地指定某种运行的mode。只有与这种指定的mode关联的源才会被监视和允许传递他们的事件,同样地,只有与这种模式关联的观察者都会收到run loop行为变化的通知。与其它模式想关联的源,直到随后在合适的模式通过循环后,都会接收到新的事件(比如,将timer加入run loop default模式下,当滚动时,timer不会收到回调,直到停止滚动回到default模式下)。 在我们的代码中,我们通过名称来唯一标识mode。在Cocoa和Core Foundation中都定义了default模式和几个常用的模式,都是通过字符串名称来指定。我们也可以自定义模式,但是我们需要手动添加至少一个input source/timers/observers。 我们可以通过使用mode来过滤掉我们不希望接收到来自不想要的通过run loop的源。大部分情况下,我们都是使用系统定义的default模式。对于子线程,我们可以使用自定义模式在关键性操作时阻止低优先级的源传递事件。注意:Modes是通过事件源来区分,而不是事件类型来区分。比如说,我们不能使用mode来匹配只有mouse-down事件或者只有键盘事件。我们可以使用modes来监听不同系统的端口,临时挂起定时器,甚至改变正在被监视的sources和run loop观察者。 表格.png Input Sources 输入源异步传递事件到你的线程。事件的源由输入源的类型来决定,也就是两种源中的其中一种: Port-based:基于端口号的输入源监听应用程序的Mach端口。 Custom Input Sources:自定义输入源监听自定义的事件源。 系统通常实现了这两种输入源。唯一的不同点是它们是如何被发出信号的。port-based源是由内核(kernel)自动发出信号,而custom sources必须手动从其它线程发出信号。 当我们创建输入源时,可以指定mode。Modes会影响任何时刻被监视的输入源。大部分情况下,我们都让run loop在default mode下运行,但是也可以指定自定义的mode。如果一个输入源不是当前所监视的model,它所产生的任何事件都会被保留直接进入正常的mode。 Port-Based Sources Cocoa和Core Foundation提供了内建支持,可以使用与port相关的对象和函数来创建基于端口的输入源。举个例子,在Cocoa中永远不需要手动创建输入源。我们只需要简单地创建一个port对象和使用NSPort的方法。port对象为我们处理所需要的输入源的创建和配置。 在Core Foundation中,我们必须手动创建port和source。在这两种情况下,我们可以使用与port opaque type关联的函数(CFMessagePortRef, or CFSocketRef) 来创建合适的对象。 Custom Input Sources 在Core Foundation中,要创建自定义输入源,我们必须使用与CFRunLoopSourceRef关联的函数。我们配置自定义输入源可以使用几个回调函数。Core Foundation会在不同点回调这些函数来配置source,处理任何到达的事件和销毁已从run loop移除的source。 除了定义在事件到达时自定义源的行为之外,我们也必须定义事件传递机制。这部分源运行在单独的线程,负责提供输入源的数据,当数据准备好可以处理时,signaling(通知相关线程)这个消息。事件传递机制是我们自己来决定,但是不需要过于复杂。 Cocoa Perform Selector Source 除了基于端口的源之外,Cocoa还定义了自定义输入源允许我们在任意线程上执行selector。就像port-based源一样,执行selector请求会在目标线程上序列化,以减少在同一个线程中出现多个方法同步执行的问题。与port-based源不同的是,执行selector源在执行完毕后会自动将自己从run loop中移除。 当执行在其它线程执行selector时,目标线程必须要有运行的run loop。当我们创建线程时,这意味着直到启动了run loop都会显式地执行selector代码。 Run Loop每次经过一个循环,就会处理队列中所有的selector,而不仅仅是处理一个。 方法和说明。 Timer Sources Timer源在未来设定的时间会同步地传递事件到你的线程。Timers是线程通知自己去做一些事情的一种方式。比如说,搜索框可以使用定时器来初始化在一定时间就自动搜索,以便提供更多地联想词给用户。 尽管它发送基于时间的通知,但定时器并不是一种实时的机制。像输入源一样,定时器只有与run loop的mode一样才会发送通知。如果timer在run loop中并不是所被监视的mode,它不会触发定时器,直到run loop的mode与timer所支持的mode一样。 同样地,如果run loop正在处理中,timer已经fire了,这时候会被中断,直到下一次通过run loop才会调志处理程序。如果run loop已经不再运行了,则timer永远不会再fire。 我们可以配置timer只产生事件一次或者重复产生。重复的timer会自动根据调度的firing time自动调度,而不是真实的firing time。比如说,如果一个timer在特定的时间调度,然后每5秒重复一次。如果firing time被延迟导致缺少一或多次调用,那么timer在缺失的周期中只会调用一次。 Run Loop Observers 与sources在适当时机异步或同步发出事件不同,observers在run loop本身执行期间,会在特定的地方发出。你可能需要到run loop observers去准备线程处理特定的事件或者在进入睡眠之前。我们可以通过以下事件来关联run loop observers: 进入runlooprunloop将要处理timer runloop将要处理输入源 runloop将要进入睡眠 runloop被唤醒,但是还没有处理事件 退出runloop 我们可以通过Core Foundation来添加run loop observers。要创建run loop observer,可以通过CFRunLoopObserverRef来创建新的实例。这个类型会跟踪你所定义的回调函数和所感兴趣的活动。 与timers类型,run-loop observers可以使用一次或者重复多次。一次性的observer会在fire之后自动从run loop移除,而重复性的observer会继续持有。 The Run Loop Sequence Of Events 本小节讲的是RunLoop事件顺序。每次运行它,你的线程的run loop处理待处理的事件和给所有attached observers发出通知。处理的顺序如下: 1.通知observersrunloop已经进入2.通知observerstimers准备要fire3.通知observers有不是基于port-based的输入源即将要fire4.fire任何已经准备好的non-port-based输入源5.如果port-based输入源准备好且等待fire,则立即处理这个事件。然后进入步骤96.通知observers线程即将进入睡眠7.让线程进入睡眠,直到以下任何一种事件到达: *port-based输入源有事件到达 *timerfire *runloop超时 *runloop被显式唤醒8.通知observers线程被唤醒9.处理待处理的事件: *如果用户定义的timerfired了,处理timer事件并重新启动循环。进入步骤2 *如果输入源fired了,则传递事件 *如果runloop被显式唤醒,但是又未超时,则重启循环,进入步骤210.通知observersrunloop退出 由于observer对timer和输入源的通知会在事件真正发生之前被传递,这样就产生了间隙。如果这个间隙是很关键的,那么我们可以通过使用sleep和awake-from-sleep通知来帮助我们纠正这个时间间隔问题。 When Would You Use A Run Loop? 什么时候应该使用run loop呢? 只有当我们需要创建子线程的时候,才会需要到显示地运行run loop。应用程序的主线程的run loop是应用启动的基础任务,在启动时就会自动启动run loop。所以我们不需要手动启动主线程的run loop。 对于子线程,我们需要确定线程是否需要run loop,如果需要,则配置它并启动它。我们并不问题需要启动run loop的。比如说,如果我们开一个子线程去执行一些长时间的和预先决定的任务,我们可能不需要启动run loop。Run loop是用于那么需要在线程中有更多地交互的场景。比如说,我们会在下面的任何一种场景中需要开启run loop: 使用端口源或者自定义输入源与其它线程通信 在线程中使用定时器 使用Cocoa中的任何performSelector…方法 保持线程来执行周期性的任务 Using Run Loop Objects Run Loop对象给添加输入源、定时器和观察者到run loop提供了主接口。每个线程都有一个单独的run loop与之关联(对于子线程,若没有调用过任何获取run loop的方法是不会有run loop的,只有调用过,才会创建或者直接使用)。 在Cocoa中,通过NSRunLoop来创建实例,在low-level应用中,可以使用CFRunLoopRef类型,它是指针。 Getting A Run Loop Object 通过以下两种方式来获取run loop对象: 在Cocoa中,使用[NSRunLoop currentRunLoop]获取 使用CFRunLoopGetCurrent()函数获取 配置RunLoop 在子线程运行run loop之前,你必须至少添加一种输入源或者定时器。如果run loop没有任何的源需要监视,它就会立刻退出。 除了添加sources之外,你还可以添加观察者来检测runloop不同的执行状态。要添加观察者,可以使用CFRunLoopObserverRef指针类型和使用CFRunLoopAddObserver函数来添加到run loop中。我们只能通过Core Foundation来创建run loop观察者,即使是Cocoa应用。 下面这段代码展示主线程如何添加观察者到run loop以及如何创建run loop观察者: -(void)threadMain{//应用程序使用垃圾收集,因此不需要autorelease池。 NSRunLoop*myRunLoop=[NSRunLoopcurrentRunLoop];//创建一个运行循环观察者并将它附加到运行循环。 CFRunLoopObserverContextcontext={0,self,NULL,NULL,NULL};CFRunLoopObserverRefobserver=CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities,YES,0,&myRunLoopObserver,&context);if(observer){CFRunLoopRefcfLoop=[myRunLoopgetCFRunLoop];CFRunLoopAddObserver(cfLoop,observer,kCFRunLoopDefaultMode); }//创建和安排计时器。 [NSTimerscheduledTimerWithTimeInterval:0.1target:self selector:@selector(doFireTimer:)userInfo:nilrepeats:YES];NSIntegerloopCount=10;do{//运行运行循环10次让计时器。 [myRunLooprunUntilDate:[NSDatedateWithTimeIntervalSinceNow:1]]; loopCount--; }while(loopCount); } 在为长时间存在的线程配置run-loop时,最好添加至少一个输入源来接收事件。尽管我们可以只用timer源,但是一旦timer调用后,经常会被invalidate,这会导致run loop退出。 Starting the Run Loop 只有子线程才有可能需要启动run loop。Run loop必须至少有一种输入源或者timer源来监视。如果没有任何源,则run loop会退出。 下面的几种方式可以启动run loop: 无条件地:无条件进入run loop是最简单的方式,但也是最不希望这么做的,因为这样会导致run loop会进入永久地循环。可以添加、删除输入源和timer源,但是只能通过kill掉run loop才能停止。而且还不能使用自定义mode。 限时:与无条件运行run loop不同,最好是给run loop添加一个超时时间。 在特定的mode:除了添加超时时间,还可以指定mode。 下面是运行run loop的一段代码: -(void)skeletonThreadMain{//建立一个autorelease如果不使用垃圾收集池。 BOOLdone=NO;//添加你的来源或计时器运行循环,做其他任何设置。 do{//启动运行循环但每个源处理后返回。 SInt32result=CFRunLoopRunInMode(kCFRunLoopDefaultMode,10,YES); //如果源明确停止运行循环,或如果没有源或计时器,然后退出。if((result==kCFRunLoopRunStopped)||(result==kCFRunLoopRunFinished)) done=YES; //检查任何其他退出条件和设置完成所需的变量。}while(!done); //清理代码。一定要释放任何生成自动分配池。 } Exiting the Run Loop 有两种方法使run loop在处理事件之前,退出run loop: 给runloop设定超时时间 告诉runloop要stop 设定超时时间是比较推荐的。我们可以通过CFRunLoopStop函数来停止run loop。 Thread Safety and Run Loop Objects Core Foundation中的Run Loop API是线程安全的(以CF开头的API),而Cocoa中的NSRunLoop不是线程安全的。 Configuring Run Loop Sources 下面是展示如何配置不同类型的输入源。 Defining a Custom Input Source 创建自定义输入源涉及到以下部分: 想要处理的输入源的信息 让感兴趣的客户端知道如何联系输入源的调度程序 执行任何客户端发送的请求处理程序 使输入源失效的取消程序 Timer Source NSRunLoop*myRunLoop=[NSRunLoopcurrentRunLoop]; //创建和安排第一个定时器。NSDate*futureDate=[NSDatedateWithTimeIntervalSinceNow:1.0];NSTimer*myTimer=[[NSTimeralloc]initWithFireDate:futureDate interval:0.1 target:self selector:@selector(myDoFireTimer1:) userInfo:nil[myRunLoopaddTimer:myTimerforMode:NSDefaultRunLoopMode]; 或者使用Core Foundation: CFRunLoopRefrunLoop=CFRunLoopGetCurrent();CFRunLoopTimerContextcontext={0,NULL,NULL,NULL,NULL};CFRunLoopTimerReftimer=CFRunLoopTimerCreate(kCFAllocatorDefault,0.1,0.3,0,0, &myCFTimerCallback,&context);CFRunLoopAddTimer(runLoop,timer,kCFRunLoopCommonModes); 最后 本篇文章主要是官方文档的部分翻译版本,不过有很多无关的都省略了,而且有都转换成笔者的语言来表达出来,如果读不懂,最好还是去看官方文档吧。毕竟,英文与中文翻译不管怎么翻译都存在很大的问题。 疑问 官方文档中提到,每个线程都有一个run loop与之关联。但是实质上子线程在没有访问过run loop时,是不存在的。当访问时,若不存在则创建run loop并放到全局数组中。 本文转自 卓行天下 51CTO博客,原文链接:http://blog.51cto.com/9951038/1766775,如需转载请自行联系原作者

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

离线安装Eclipse的Android ADT开发插件

不知道大家是不是有过这样的感觉。从 https://dl-ssl.google.com/android/eclipse/ 很慢呢!我是教育网所以确实是很慢的。 所以我想了一个办法确保可以快点安装上ADT15。当然ADT16、ADT17也是可以的。不过我还是用ADT15做演示把。 很熟悉把,这是Eclipse解压后的图片当然ADT是要自己下载的。我们51CTO下载哪儿也有好多的,大家自己去下载,我就不提供下载地址啦。 打开Eclipse, 在菜单栏上选择 help->Install New SoftWare 出现如下界面: 点击 Add按钮,出现如下界面 在Name这而随意输入一个名字:ADT15; 点击打开Archives如图: 记得啦ADT一定要是ZIP格式的呢。 打开后如图: 点击“Next”: 再次点击“Next”: 选择“I accept the ......”,就可以点击“Finish”啦: 嘻嘻,Eclipse问你要安装吗。肯定是“OK”: 继续选择“OK” Eclipse问你要重启Eclipse吗?当然要啦,不然怎么使用ADT。还是“OK”: 重启Eclipse后,点击菜单window->preferences,进入如下界面 选择你的android SDK解压后的目录,选错了就会报错,这个是升级工具,目前还没有一个版本的SDK。 就可以安装好啦。 读者可以参考:http://mobile.51cto.com/android-227548.htm 希望我的博文对大家有帮助。有疑问可以留言呢。 本文转自 梦朝思夕 51CTO博客,原文链接:http://blog.51cto.com/qiangmzsx/828182

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

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

Rocky Linux

Rocky Linux

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

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册