首页 文章 精选 留言 我的

精选列表

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

安卓开发整理

先来一个HelloWorld. XML布局文件 <?xml version="1.0" encoding="utf-8"?> <!--线性布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World" /> </LinearLayout> 事件响应代码为将英文修改成中文。 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置屏幕组件需要用的布局 setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.tv); // 修改文本控件的文字 tv.setText("你好,世界"); } } 最后在手机上显示的画面如下 创建第二个页面 在res/layout文件夹下面新建一个xml文件 在res/values的strings.xml文件中添加内容 <resources> <string name="app_name">OCR</string> <string name="text2">Activity Main2</string> </resources> activity_main2.xml的布局内容如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text2" /> </LinearLayout> 在清单文件AndroidManifest.xml文件中添加activity_main2的配置。 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.guanjian.ocr"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.OCR"> <activity android:name=".MainActivity" android:exported="true" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity2" /> </application> </manifest> 在Activity1中添加一个按钮来跳转到Activity2。 <?xml version="1.0" encoding="utf-8"?> <!--线性布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转" /> </LinearLayout> 修改MainActivity的Java代码 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置屏幕组件需要用的布局 setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.tv); // 修改文本控件的文字 tv.setText("你好,世界"); Button button = findViewById(R.id.button); // 给button设定点击事件的侦听 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 创建一个意图对象 Intent intent = new Intent(); intent.setClass(MainActivity.this,MainActivity2.class); // 实现跳转 startActivity(intent); } }); } } 在Java主目录中创建MainActivity2的响应类。 public class MainActivity2 extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); } } 在手机上的运行效果如下 Activity生命周期 上图的说明可以见以下代码 public class MainActivity extends AppCompatActivity { private static final String TAG = "ning"; /** * 在页面载入的时候最先触发 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG,"Activity onCreate"); // 设置屏幕组件需要用的布局 setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.tv); // 修改文本控件的文字 tv.setText("你好,世界"); Button button = findViewById(R.id.button); // 给button设定点击事件的侦听 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 创建一个意图对象 Intent intent = new Intent(); intent.setClass(MainActivity.this,MainActivity2.class); // 实现跳转 startActivity(intent); } }); } /** * 在页面载入的时候第二个触发 */ @Override protected void onStart() { super.onStart(); Log.d(TAG,"Activity onStart"); } /** * 在页面载入的时候第三个触发,结束时页面可见 */ @Override protected void onResume() { super.onResume(); Log.d(TAG,"Activity onResume"); } /** * 在页面跳转离开的时候触发 */ @Override protected void onPause() { super.onPause(); Log.d(TAG,"Activity onPause"); } /** * 在页面完全消失的时候触发 */ @Override protected void onStop() { super.onStop(); Log.d(TAG,"Activity onStop"); } /** * 从其他页面返回该页面时首次执行 * 然后执行onStart和onResume */ @Override protected void onRestart() { super.onRestart(); Log.d(TAG,"Activity onRestart"); } /** * 从主界面返回安卓桌面的时候触发 */ @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG,"Activity onDestroy"); } } 当我们打开安卓app的时候会显示日志 D/ning: Activity onCreate D/ning: Activity onStart D/ning: Activity onResume 当我们点击跳转按钮会显示日志 D/ning: Activity onPause D/ning: Activity onStop 当我们从跳转页面返回主界面时会显示日志 D/ning: Activity onRestart D/ning: Activity onStart D/ning: Activity onResume 当我们从主界面返回安卓桌面时会显示日志 D/ning: Activity onPause D/ning: Activity onStop D/ning: Activity onDestroy 当我们点击了跳转按钮立刻返回主界面时会显示日志 D/ning: Activity onPause D/ning: Activity onResume 这里有一个值得说明的地方,当App隐藏于后台的时候,我们启动了非常占用内存的App,比如游戏,此时安卓系统会将该进程杀死释放内存给游戏使用。当我们再次进入该App的时候会显示D/ning: Activity onCreate而不是D/ning: Activity onRestart。这几个触发动作的具体应用如下 onCreate:创建活动,把页面布局加载进内存,进入初始状态。 onStart:开始活动,把活动页面显示在屏幕上,进入了就绪状态。 onResume:恢复活动,活动页面进入活跃状态,能够与用户正常交互,例如允许响应用户的点击动作;允许用户输入文字等等。 onPause:暂停活动,页面进入暂停状态,无法与用户进行正常交互。 onStop:停止活动,页面将不在屏幕上显示。 onDestroy:销毁活动,回收活动占用的系统资源,把页面从内存中清除。 onRestart:重启活动,重新加载内存中的页面数据。 onNewIntent:重用已有的活动实例。 Intent Intent是各个组件之间信息沟通的桥梁,它用于Android各组件之间的通信,主要完成下列工作: 标明本次通信请求从哪里来,到哪里去,要怎么走。 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析数据。 发起方若想判断接收方的处理结果,意图就要负责接收方传回应答的数据内容。 显式Intent:直接指定来源活动与目标活动,属于精确匹配。它有3种构建方式 在Intent的构造函数中指定。 调用意图对象的setClass方法指定。 调用意图对象的setComponent方法指定。 @Override public void onClick(View view) { // 创建一个意图对象,第一种方式 // Intent intent = new Intent(MainActivity.this,MainActivity2.class); // 第二种方式 Intent intent = new Intent(); intent.setClass(MainActivity.this,MainActivity2.class); // 第三种方式 // Intent intent = new Intent(); // 它可以调用第三方的控件,使用包名(字符串)和类名(字符串)来调用 // ComponentName component = new ComponentName(MainActivity.this,MainActivity2.class); // intent.setComponent(component); // 实现跳转 startActivity(intent); } 隐式Intent:没有明确指定要跳转的目标活动,只给出一个动作字符串让系统自动匹配,属于模糊匹配。 现在我们在Activity2的页面中添加如下的布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text2" /> <TextView android:id="@+id/tv3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:text="点击以下按钮将向号码12345发起请求" /> <Button android:id="@+id/btn_dial" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="跳到拨号页面" /> </LinearLayout> 在Activity2的Java代码中添加 public class MainActivity2 extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); findViewById(R.id.btn_dial).setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_dial: Intent intent = new Intent(); // 隐式跳转到拨号界面 intent.setAction(Intent.ACTION_DIAL); Uri uri = Uri.parse("tel:12345"); intent.setData(uri); startActivity(intent); break; default: break; } } } 运行结果 向下一个Activity传递数据 我们在Activity的主界面的布局文件中添加如下代码 <?xml version="1.0" encoding="utf-8"?> <!--线性布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转" /> <TextView android:id="@+id/tv_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="今天天气很晴朗" /> <Button android:id="@+id/button_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送信息" /> </LinearLayout> 在Activity的Java代码中添加 public class MainActivity extends AppCompatActivity { private static final String TAG = "ning"; private TextView tvSend; /** * 在页面载入的时候最先触发 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG,"Activity onCreate"); // 设置屏幕组件需要用的布局 setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.tv); // 修改文本控件的文字 tv.setText("你好,世界"); Button button = findViewById(R.id.button); // 给button设定点击事件的侦听 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 创建一个意图对象,第一种方式 // Intent intent = new Intent(MainActivity.this,MainActivity2.class); // 第二种方式 Intent intent = new Intent(); intent.setClass(MainActivity.this,MainActivity2.class); // 第三种方式 // Intent intent = new Intent(); // 它可以调用第三方的控件,使用包名(字符串)和类名(字符串)来调用 // ComponentName component = new ComponentName(MainActivity.this,MainActivity2.class); // intent.setComponent(component); // 实现跳转 startActivity(intent); } }); tvSend = findViewById(R.id.tv_send); findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this,MainActivity2.class); // 创建一个包裹对象 Bundle bundle = new Bundle(); bundle.putString("request_time", new Date().toString()); bundle.putString("request_context",tvSend.getText().toString()); intent.putExtras(bundle); startActivity(intent); } }); } /** * 在页面载入的时候第二个触发 */ @Override protected void onStart() { super.onStart(); Log.d(TAG,"Activity onStart"); } /** * 在页面载入的时候第三个触发,结束时页面可见 */ @Override protected void onResume() { super.onResume(); Log.d(TAG,"Activity onResume"); } /** * 在页面跳转离开的时候触发 */ @Override protected void onPause() { super.onPause(); Log.d(TAG,"Activity onPause"); } /** * 在页面完全消失的时候触发 */ @Override protected void onStop() { super.onStop(); Log.d(TAG,"Activity onStop"); } /** * 从其他页面返回该页面时首次执行 * 然后执行onStart和onResume */ @Override protected void onRestart() { super.onRestart(); Log.d(TAG,"Activity onRestart"); } /** * 从主界面返回安卓桌面的时候触发 */ @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG,"Activity onDestroy"); } } 在Activity2中获取意图中的数据放入tv2中。 public class MainActivity2 extends AppCompatActivity implements View.OnClickListener { private TextView tv2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); findViewById(R.id.btn_dial).setOnClickListener(this); tv2 = findViewById(R.id.tv2); // 从上一个页面的意图中获取包裹 Bundle bundle = getIntent().getExtras(); String requestTime = bundle.getString("request_time"); String requestContext = bundle.getString("request_context"); String desc = String.format("收到请求消息:\n请求时间:%s\n请求内容:%s", requestTime,requestContext); tv2.setText(desc); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_dial: Intent intent = new Intent(); // 隐式跳转到拨号界面 intent.setAction(Intent.ACTION_DIAL); Uri uri = Uri.parse("tel:12345"); intent.setData(uri); startActivity(intent); break; default: break; } } } 运行结果 向上一个Activity返回数据 现在我们要回一个信息给到主界面,说今天天气很热。 在Activity2中增加一个按钮,布局文件如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text2" /> <TextView android:id="@+id/tv_response" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="待返回的消息为:今天天气很热" /> <Button android:id="@+id/btn_response" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送返回信息" /> <TextView android:id="@+id/tv3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" android:text="点击以下按钮将向号码12345发起请求" /> <Button android:id="@+id/btn_dial" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="跳到拨号页面" /> </LinearLayout> 现在我们在Activity的主界面的Java代码中就不仅仅是普通的跳转到Activity2了,而是需要注册一个可以等待返回的ActivityResult。跳转的方式也不再是startActivity(intent);注意,以下代码都改成了Lambda表达式的形式,关于lambda表达式的内容可以参考Java函数式编程整理 。 public class MainActivity extends AppCompatActivity { private static final String TAG = "ning"; private TextView tvSend; private ActivityResultLauncher<Intent> register; /** * 在页面载入的时候最先触发 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG,"Activity onCreate"); // 设置屏幕组件需要用的布局 setContentView(R.layout.activity_main); TextView tv = findViewById(R.id.tv); // 修改文本控件的文字 tv.setText("你好,世界"); Button button = findViewById(R.id.button); // 给button设定点击事件的侦听 button.setOnClickListener(view -> { // 创建一个意图对象,第一种方式 // Intent intent = new Intent(MainActivity.this,MainActivity2.class); // 第二种方式 Intent intent = new Intent(); intent.setClass(MainActivity.this,MainActivity2.class); // 第三种方式 // Intent intent = new Intent(); // 它可以调用第三方的控件,使用包名(字符串)和类名(字符串)来调用 // ComponentName component = new ComponentName(MainActivity.this,MainActivity2.class); // intent.setComponent(component); // 实现跳转 startActivity(intent); }); tvSend = findViewById(R.id.tv_send); // 注册ActivityResult,并通过回调函数获取返回的信息 register = registerForActivityResult(new StartActivityForResult(), result -> { if (result != null) { Intent intent = result.getData(); if (intent != null && result.getResultCode() == Activity.RESULT_OK) { Bundle bundle = intent.getExtras(); String responseTime = bundle.getString("response_time"); String responseContext = bundle.getString("response_context"); String desc = String.format("收到返回消息:\n返回时间:%s\n返回内容:%s", responseTime,responseContext); tv.setText(desc); } } }); findViewById(R.id.button_send).setOnClickListener(view -> { Intent intent = new Intent(MainActivity.this,MainActivity2.class); // 创建一个包裹对象 Bundle bundle = new Bundle(); bundle.putString("request_time", new Date().toString()); bundle.putString("request_context",tvSend.getText().toString()); intent.putExtras(bundle); register.launch(intent); }); } /** * 在页面载入的时候第二个触发 */ @Override protected void onStart() { super.onStart(); Log.d(TAG,"Activity onStart"); } /** * 在页面载入的时候第三个触发,结束时页面可见 */ @Override protected void onResume() { super.onResume(); Log.d(TAG,"Activity onResume"); } /** * 在页面跳转离开的时候触发 */ @Override protected void onPause() { super.onPause(); Log.d(TAG,"Activity onPause"); } /** * 在页面完全消失的时候触发 */ @Override protected void onStop() { super.onStop(); Log.d(TAG,"Activity onStop"); } /** * 从其他页面返回该页面时首次执行 * 然后执行onStart和onResume */ @Override protected void onRestart() { super.onRestart(); Log.d(TAG,"Activity onRestart"); } /** * 从主界面返回安卓桌面的时候触发 */ @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG,"Activity onDestroy"); } } Activity2中的返回信息的代码如下 public class MainActivity2 extends AppCompatActivity implements View.OnClickListener { private TextView tv2; private final String msg = "今天天气很热"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); findViewById(R.id.btn_dial).setOnClickListener(this); tv2 = findViewById(R.id.tv2); // 从上一个页面的意图中获取包裹 Bundle bundle = getIntent().getExtras(); String requestTime = bundle.getString("request_time"); String requestContext = bundle.getString("request_context"); String desc = String.format("收到请求消息:\n请求时间:%s\n请求内容:%s", requestTime,requestContext); tv2.setText(desc); findViewById(R.id.btn_response).setOnClickListener(this); } @Override public void onClick(View view) { Intent intent = new Intent(); switch (view.getId()) { case R.id.btn_dial: // 隐式跳转到拨号界面 intent.setAction(Intent.ACTION_DIAL); Uri uri = Uri.parse("tel:12345"); intent.setData(uri); startActivity(intent); break; case R.id.btn_response: Bundle bundle = new Bundle(); bundle.putString("response_time",new Date().toString()); bundle.putString("response_context",msg); intent.putExtras(bundle); setResult(Activity.RESULT_OK,intent); // 页面返回跳转 finish(); break; default: break; } } } 运行结果 运行时动态申请权限 安卓系统在6.0之前,只需要在清单文件中去配置权限就可以使用例如手机联系人、短信、相册等需要申请权限的应用。用户在安装的时候会进行提示。在安卓6.0之后不仅仅需要在清单文件中配置这些权限,而且会进行系统弹窗的询问,要使用这些权限需要在用户允许的情况下才可以使用。 Lazy模式 Lazy模式即懒汉式模式,当我们需要用到某个权限功能时才去请求权限。除此之外还有一个Hungry模式,即饿汉式模式,当我们打开App的时候,不管你有没有使用到某个权限功能,它都会对用户进行请求,让用户去一次性通过。 我们在Activity的布局文件中添加两个按钮去读取通讯录和发送短信。 <?xml version="1.0" encoding="utf-8"?> <!--线性布局--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="跳转" /> <TextView android:id="@+id/tv_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="今天天气很晴朗" /> <Button android:id="@+id/button_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送信息" /> <Button android:id="@+id/btn_contact" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="读写通讯录" /> <Button android:id="@+id/btn_sms" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送短信" /> </LinearLayout>

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

Python开发环境pipenv

使用pipenv(官方推荐) pipenv只是一个工具,我们用这个工具来创建虚拟环境;我们用pipenv来创建一个虚拟环境,这个虚拟环境是和项目绑定的,也就是我们每创建一个项目就要创建一个虚拟环境 安装: pip install pipenv 为项目安装独立的虚拟环境 # 进入项目相应的目录以后 pipenv install image.png image.png 启动pipenv 启动 # 在项目目录下执行 pip shell image.png 退出 exit image.png 安装包 pipenv install flask 卸载包 pipenv uninstall flask image.png 查看包之间的依赖关系 pipenv graph image.png 查看虚拟环境的路径 image.png 安装各种包,比如Flask pipenv install flask

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

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

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

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

用户登录
用户注册