Android 应用开发】Android 数据存储 之 SQLite数据库详解(二·)

简介: Android 应用开发】Android 数据存储 之 SQLite数据库详解(二)

2. 详细代码



SQLiteDataBase示例程序下载地址 :


-- GirHub - https://github.com/han1202012/SQLite_NewsList.git.




(1) MainActivity代码




package shuliang.han.database;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity {
  private SQLiteDatabase db;  //数据库对象
  private ListView listView;  //列表
  private EditText et_tittle; //输入的新闻标题
  private EditText et_content;  //输入的新闻内容
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //打开或者创建数据库, 这里是创建数据库
  db = SQLiteDatabase.openOrCreateDatabase(this.getFilesDir().toString() + "/news.db", null);
  System.out.println(this.getFilesDir().toString() + "/news.db");
  //初始化组件
  listView = (ListView) findViewById(R.id.lv_news);
  et_tittle = (EditText) findViewById(R.id.et_news_tittle);
  et_content = (EditText) findViewById(R.id.et_news_content);
  }
  /*
  * 插入数据到数据库中的触发点击事件
  * 如果数据库存在就能正常访问数据库, 如果不存在访问数据库的时候就会出现 SQLiteException 异常
  * 正常访问 : 获取输入的新闻标题 和 新闻内容, 将标题 和 内容插入到数据库, 重新获取Cursor, 使用Cursor刷新ListView内容
  * 异常访问 : 如果访问出现了SQLiteException异常, 说明数据库不存在, 这时就需要先创建数据库
  */
  public void insertNews(View view) {
  String tittle = et_tittle.getText().toString();
  String content = et_content.getText().toString();
  try{
    insertData(db, tittle, content);
    Cursor cursor = db.rawQuery("select * from news_table", null);
    inflateListView(cursor);
  }catch(SQLiteException exception){
    db.execSQL("create table news_table (" +
      "_id integer primary key autoincrement, " +
      "news_tittle varchar(50), " +
      "news_content varchar(5000))");
    insertData(db, tittle, content);
    Cursor cursor = db.rawQuery("select * from news_table", null);
    inflateListView(cursor);
  }
  }
  /*
  * 向数据库中插入数据
  * 参数介绍 : 
  * -- 参数① : SQL语句, 在这个语句中使用 ? 作为占位符, 占位符中的内容在后面的字符串中按照顺序进行替换
  * -- 参数② : 替换参数①中占位符中的内容
  */
  private void insertData(SQLiteDatabase db, String tittle, String content) {
  db.execSQL("insert into news_table values(null, ?, ?)", new String[]{tittle, content});
  }
  /*
  * 刷新数据库列表显示
  * 1. 关联SimpleCursorAdapter与数据库表, 获取数据库表中的最新数据
  * 2. 将最新的SimpleCursorAdapter设置给ListView
  */
  private void inflateListView(Cursor cursor) {
  SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(
    getApplicationContext(), 
    R.layout.item, 
    cursor, 
    new String[]{"news_tittle", "news_content"}, 
    new int[]{R.id.tittle, R.id.content});
  listView.setAdapter(cursorAdapter);
  }
  @Override
  protected void onDestroy() {
  super.onDestroy();
  //在Activity销毁的时候, 如果没有
  if(db != null && db.isOpen())
    db.close();
  }
}


(2) XML布局文件



主布局文件 :



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" 
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新闻标题" />
    <EditText 
        android:id="@+id/et_news_tittle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:hint="点击此处输入新闻标题"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新闻内容" />
    <EditText 
        android:id="@+id/et_news_content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:lines="2"
        android:hint="点击此处输入新闻内容"/>
    <Button
        android:id="@+id/bt_add_news"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="insertNews"
        android:text="添加新闻" />
    <ListView 
        android:id="@+id/lv_news"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
</LinearLayout>



ListView条目布局文件 :


<?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" >
    <TextView 
        android:id="@+id/tittle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:textColor="#FFFF00"/>
    <TextView 
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="10dp"
        android:textColor="#00FF00"/>
</LinearLayout>

效果图 :



image.png





三. SQLiteOpenHelper类操作数据库



单独使用SQLiteDataBase操作数据库的弊端: 对数据库的表进行操作的时候, 我们不知道数据库中表是否存在, 首先要进行表操作, 在出现异常之后, 在异常捕获的try catch 代码块中创建表, 这样操作很繁琐;




SQLiteOpenHelper作用 : 该类用来管理数据库的创建 和版本更新, 通常使用其子类, 实现onCreate() 和 onUpgrade()方法;




1. 类中的方法介绍



(1) 读写打开数据库



以读写的方式打开数据库 :先以读写方式打开数据库, 如果磁盘满了, 就会打开失败,然后会尝试以只读的方式打开数据库;



public SQLiteDatabase getReadableDatabase ()



(2) 写方式打开数据库



以写的方式打开数据库 :先以读写方式打开数据库, 如果磁盘满了, 就会出错,不推荐使用这种方法, 使用 getReadableDatabase()方法即可;



public SQLiteDatabase getWritableDatabase ()


(3) 创建数据库



创建数据库 : 第一次创建数据库的时候回调该方法, 一般在该方法中 创建数据库表;



public abstract void onCreate (SQLiteDatabase db)

方法解析 :

-- 调用时机: 当使用getReadableDatabase()方法 获取数据库 实例 的时候, 如果数据库不存在, 就会调用这个方法;


-- 方法内容 : 重写该方法一般 将 创建数据库表的 execSQL()方法 和 初始化表数据的一些 insert()方法写在里面;





(4) 更新数据库



更新数据库 : 升级软件的时候更新数据库表结构, 在数据库版本发生变化的时候调用;



public abstract void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion)

方法解析 :

-- 调用时机 : 数据库版本发生变化的时候回调, newVersion是当前数据库版本号, oldVersion是旧的版本号;


-- 识别版本 : 创建SQLiteOpenHelper子类对象的时候,必须传入一个version参数, 该参数就是当前数据库版本, 只要这个版本高于之前的版本, 就会触发这个onUpgrade()方法;






(5) 关闭数据库



关闭打开的数据库 :



public synchronized void close ()



2. 示例程序要点解析



(1) 在onCreate()方法中创建表



创建数据库表 : 定义一个数据库SQL语句, 之后在onCreate()方法中 execSQL()执行该语句;


final String SQL_CREATE_TABLE = "create table news_table (" +
    "_id integer primary key autoincrement, " +
    "news_tittle varchar(50), " +
    "news_content varchar(5000))";
  @Override
  public void onCreate(SQLiteDatabase db) {
  db.execSQL(SQL_CREATE_TABLE);
  }



(2) 插入数据



插入内容 : 打开数据库,如果存在直接插入内容, 如果不存在就创建表在插入内容;



 

helper.getReadableDatabase().execSQL("insert into news_table values(null, ?, ?)", 
    new String[]{tittle, content});


(3) 查询数据库



查询数据 : 使用SQLiteOpenHelper子类对象打开数据库, 并且执行查询语句;



Cursor cursor = helper.getReadableDatabase().rawQuery("select * from news_table", null);


(4) 解析Cursor记录



将Cursor中的数据转为 ArrayList<Map<String, String>> 类型数据 :


-- 遍历条件 : Cursor的moveToNext()方法, 如果成功移到下一个记录, 就执行循环内容;


-- 获取表中数据 : Cursor的getString(1) 就是获取 这一样记录中的 第二列的数据, 第一列是 "_id" 主键;



private ArrayList<Map<String, String>> cursor2list(Cursor cursor) {
  ArrayList<Map<String, String>> list = new ArrayList<Map<String,String>>();
  //遍历Cursor
  while(cursor.moveToNext()){
    Map<String, String> map = new HashMap<String, String>();
    map.put("tittle", cursor.getString(1));
    map.put("content", cursor.getString(2));
    list.add(map);
  }
  return list;
  }


(5) 开启一个Activity并传递数据



流程 :


-- ① 创建Bundle对象 : 该对象可以存放数据, 并可以放到Intent对象中, 传递给另外的组件;


-- ② Bundle存数据 : 使用putSerializable()方法, 可以存放对象, 将 ArrayList<Map<String, String>> 存入里面;


-- ③ 创建Intent对象 : 传入要跳转的Activity的Class对象;


-- ④ Bundle加入Intent对象 : 将存放好数据的Bundle对象加入到Intent对象中;


-- ⑤ 开启Activity : 使用startActivity(intent)方法跳转Activity;



Bundle bundle = new Bundle();
  bundle.putSerializable("news", cursor2list(cursor));
  Intent intent = new Intent(this, SearchResultActivity.class);
  intent.putExtras(bundle);
  startActivity(intent);



(6) 在Activity中获取Intent传递的数据



执行流程 :


-- 获取Intent对象: 调用 getIntent()方法, 可以获取Activity跳转到额Intent对象;


-- 获取Bundle对象 : Intent对象调用 getExtras()方法, 可以获取存放数据的Bundle对象;


-- 将数据从Bundle对象取出 : 调用getSerializable()方法, 并将返回值转换成 List<Map<String, String>> 类型;



 //获取跳转到该Activity的intent对象

 Intent intent = getIntent();

 //获取Intent对象所携带的数据

 Bundle bundle = intent.getExtras();

 //从Bundle中取出List<Map<String,String>>数据

 @SuppressWarnings("unchecked")

 List<Map<String, String>> list = (List<Map<String, String>>)bundle.getSerializable("news");



(7) 适配器转化



将 List<Map<String, String>> 类型数据转为 SimpleAdapter类型适配器 :


参数介绍 :


-- 参数① context : 上下文对象;


-- 参数②List<Map<String, String>> : 数据源;


-- 参数③ id : ListView元素条目布局文件;


-- 参数④ string[] : 数据源中Map对象的键;


-- 参数⑤ int[]: 数据源中Map每个键对应的值 存放的组件 id;


SimpleAdapter adapter = new SimpleAdapter(
    getApplicationContext(),  //上下文对象
    list,       //数据源
    R.layout.item,      //List显示布局
    new String[]{"tittle", "content"}, //List中map的键值
    new int[]{R.id.tittle, R.id.content});  //填充到的布局文件



3. 实例程序源码



(1) SQLiteOpenHelper源码




package shuliang.han.newssearch;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class NewsSearchDatabaseHelper extends SQLiteOpenHelper {
  final String SQL_CREATE_TABLE = "create table news_table (" +
    "_id integer primary key autoincrement, " +
    "news_tittle varchar(50), " +
    "news_content varchar(5000))";
  /*
  * 构造方法 : 
  * 参数介绍 : 
  * 参数① : 上下文对象
  * 参数② : 数据库名称
  * 参数③ : 数据库版本号
  */
  public NewsSearchDatabaseHelper(Context context, String name, int version) {
  super(context, name, null, version);
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
  db.execSQL(SQL_CREATE_TABLE);
  }
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  System.out.println("call update");
  }
}


(2) MainActivity源码




package shuliang.han.newssearch;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity {
  private NewsSearchDatabaseHelper helper;  //数据库帮助类
  private EditText et_tittle;     //输入新闻标题
  private EditText et_content;    //输入新闻内容
  private ListView listView;      //显示新闻列表
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  helper = new NewsSearchDatabaseHelper(getApplicationContext(), "news", 1);
  //初始化控件
  et_tittle = (EditText) findViewById(R.id.et_news_tittle);
  et_content = (EditText) findViewById(R.id.et_news_content);
  listView = (ListView) findViewById(R.id.lv_news);
  }
  /*
  * 按钮点击事件
  * 通过判断被点击的组件, 执行不同的操作
  */
  public void onClick(View view) {
  int id = view.getId();
  switch (id) {
    case R.id.bt_add_news:
    insertNews();
    break;
    case R.id.bt_query_news:
    queryNews();
    break;
    default:
    break;
  }
  }
  /*
  * 插入新闻数据
  * 1. 从EditText组件中获取新闻的标题 和 新闻内容
  * 2. 获取数据库并从将 新闻标题 和 内容 插入到数据库中
  * 3. 重新查询数据库 获得Cursor对象
  * 4. 根据cursor对象创建SimpleCursorAdapter对象
  * 5. 将SimpleCursorAdapter设置给ListView, 显示新闻列表
  */
  private void insertNews() {
  String tittle = et_tittle.getText().toString();
  String content = et_content.getText().toString();
  helper.getReadableDatabase().execSQL("insert into news_table values(null, ?, ?)", 
    new String[]{tittle, content});
  Cursor cursor = helper.getReadableDatabase().rawQuery("select * from news_table", null);
  inflateListView(cursor);
  }
  /*
  * 刷新数据库列表显示
  * 1. 关联SimpleCursorAdapter与数据库表, 获取数据库表中的最新数据
  * 2. 将最新的SimpleCursorAdapter设置给ListView
  */
  private void inflateListView(Cursor cursor) {
  SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(
    getApplicationContext(), 
    R.layout.item, 
    cursor, 
    new String[]{"news_tittle", "news_content"}, 
    new int[]{R.id.tittle, R.id.content});
  listView.setAdapter(cursorAdapter);
  }
  /*
  * 查询新闻
  * 1. 获取要查询的新闻标题 和 新闻内容
  * 2. 查询数据库 获取 Cursor, 并将Cursor转化为List<Map<String, String>>类型的集合
  * 3. 将集合放入bundle, Intent开启另一个Activity, 将bundle放入intent对象, 跳转Activity
  * 
  */
  private void queryNews() {
  String tittle = et_tittle.getText().toString();
  String content = et_content.getText().toString();
  Cursor cursor = helper.getReadableDatabase().rawQuery(
    "select * from news_table where news_tittle like ? or news_content like ?", 
    new String[]{"%" + tittle + "%", "%" + content + "%"});
  Bundle bundle = new Bundle();
  bundle.putSerializable("news", cursor2list(cursor));
  Intent intent = new Intent(this, SearchResultActivity.class);
  intent.putExtras(bundle);
  startActivity(intent);
  }
  /*
  * 返回一个ArrayList集合, 这个集合中每个元素是一个Map集合, 每个Map集合有两个元素
  * 解析Cursor对象 : 
  * 1. cursor光标向下移动一格; 
  * 2. 创建一个HashMap对象
  * 3. 使用 cursor.getString(列标号)获取该行中某列值, 将这个值放入map中
  * 4. 将Map对象放入
  */
  private ArrayList<Map<String, String>> cursor2list(Cursor cursor) {
  ArrayList<Map<String, String>> list = new ArrayList<Map<String,String>>();
  //遍历Cursor
  while(cursor.moveToNext()){
    Map<String, String> map = new HashMap<String, String>();
    map.put("tittle", cursor.getString(1));
    map.put("content", cursor.getString(2));
    list.add(map);
  }
  return list;
  }
  @Override
  protected void onDestroy() {
  super.onDestroy();
  //释放数据库资源
  if(helper !=null)
    helper.close();
  }
}



(3) SearchResultActivity源码




package shuliang.han.newssearch;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class SearchResultActivity extends Activity {
  private ListView listView;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  //设置布局文件
  setContentView(R.layout.news_search_result);
  //初始化组件
  listView = (ListView) findViewById(R.id.lv_search_result);
  //获取跳转到该Activity的intent对象
  Intent intent = getIntent();
  //获取Intent对象所携带的数据
  Bundle bundle = intent.getExtras();
  //从Bundle中取出List<Map<String,String>>数据
  @SuppressWarnings("unchecked")
  List<Map<String, String>> list = (List<Map<String, String>>)bundle.getSerializable("news");
  SimpleAdapter adapter = new SimpleAdapter(
    getApplicationContext(),  //上下文对象
    list,       //数据源
    R.layout.item,      //List显示布局
    new String[]{"tittle", "content"}, //List中map的键值
    new int[]{R.id.tittle, R.id.content});  //填充到的布局文件
  listView.setAdapter(adapter);
  }
}




(4) XML文件



主界面布局 :



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" 
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新闻标题" />
    <EditText 
        android:id="@+id/et_news_tittle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:hint="点击此处输入新闻标题"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="新闻内容" />
    <EditText 
        android:id="@+id/et_news_content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:lines="2"
        android:hint="点击此处输入新闻内容"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_gravity="center_horizontal">
     <Button
         android:id="@+id/bt_add_news"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:onClick="onClick"
         android:text="添加新闻" />
     <Button
         android:id="@+id/bt_query_news"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:onClick="onClick"
         android:text="查找新闻" />
    </LinearLayout>
    <ListView 
        android:id="@+id/lv_news"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
</LinearLayout>
ListView条目布局 : 
<?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" >
    <TextView 
        android:id="@+id/tittle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:textColor="#FFFF00"/>
    <TextView 
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="10dp"
        android:textColor="#00FF00"/>
</LinearLayout>
跳转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" >
  <ListView 
     android:id="@+id/lv_search_result"
     android:layout_height="wrap_content"
     android:layout_width="wrap_content"/>
</LinearLayout>



SQLiteOpenHelper示例程序下载地址 :


-- GitHub : https://github.com/han1202012/NewsSearch.git .




效果图 :

image.png


目录
相关文章
|
存储 XML 开发工具
探索安卓应用开发:从基础到进阶
在这篇文章中,我们将一起踏上安卓应用开发的旅程。不论你是编程新手还是希望提升技能的开发者,这里都有你需要的东西。我们会从最基础的概念开始,逐步深入到更复杂的主题。文章将涵盖开发环境设置、用户界面设计、数据处理以及性能优化等方面。通过理论与实践的结合,你将能够构建出既美观又高效的安卓应用。让我们一起开启这段技术之旅吧!
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
11月前
|
存储 数据库 开发者
Python SQLite模块:轻量级数据库的实战指南
本文深入讲解Python内置sqlite3模块的实战应用,涵盖数据库连接、CRUD操作、事务管理、性能优化及高级特性,结合完整案例,助你快速掌握SQLite在小型项目中的高效使用,是Python开发者必备的轻量级数据库指南。
849 0
|
SQL 数据库连接 数据库
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
904 14
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
1459 15
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
268 2
|
缓存 监控 前端开发
探索Android应用开发之旅:从新手到专家
【10月更文挑战第42天】本文将带你踏上Android应用开发的旅程,无论你是初学者还是有经验的开发者。我们将一起探索如何从零开始创建你的第一个Android应用,并逐步深入到更高级的主题,如自定义视图、网络编程和性能优化。通过实际示例和清晰的解释,你将学会如何构建高效、吸引人的Android应用。让我们一起开启这段激动人心的旅程吧!
269 2
|
开发框架 前端开发 Android开发
探索安卓和iOS应用开发中的跨平台解决方案
【10月更文挑战第42天】在移动应用开发的广阔天地中,安卓和iOS系统如同两座巍峨的山峰,分别占据着半壁江山。开发者们在这两座山峰之间穿梭,努力寻找一种既能节省资源又能提高效率的跨平台开发方案。本文将带你走进跨平台开发的世界,探讨各种解决方案的优势与局限,并分享一些实用的代码示例,助你在应用开发的道路上更加游刃有余。
|
前端开发 Android开发 UED
安卓应用开发中的自定义控件实践
【10月更文挑战第35天】在移动应用开发中,自定义控件是提升用户体验、增强界面表现力的重要手段。本文将通过一个安卓自定义控件的创建过程,展示如何从零开始构建一个具有交互功能的自定义视图。我们将探索关键概念和步骤,包括继承View类、处理测量与布局、绘制以及事件处理。最终,我们将实现一个简单的圆形进度条,并分析其性能优化。
|
存储 数据库连接 数据库
Android数据存储:解释SQLite数据库在Android中的使用。
Android数据存储:解释SQLite数据库在Android中的使用。
370 0

热门文章

最新文章