09_Android中ContentProvider和Sqllite混合操作,一个项目调用另外一个项目的ContentProvider

简介: 1、  编写ContentPrivider提供者的Android应用清单文件<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.itheima28.sqlitede

1、  编写ContentPrivider提供者的Android应用

清单文件

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.itheima28.sqlitedemo"

    android:versionCode="1"

    android:versionName="1.0" >

 

    <instrumentation

        android:name="android.test.InstrumentationTestRunner"

        android:targetPackage="com.itheima28.sqlitedemo" >

    </instrumentation>

 

    <permission android:name="aa.bb.cc.read" ></permission>

    <permission android:name="aa.bb.cc.write" ></permission>

 

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="19" />

 

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <uses-library android:name="android.test.runner" />

 

        <activity

            android:name="com.itheima28.sqlitedemo.MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

 

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

       

        <!—注意加上:android:exported="true",通过它来避免出错-à

        <provider

            android:name=".providers.PersonContentProvider"

            android:authorities="com.itheima28.sqlitedemo.providers.PersonContentProvider"

            android:readPermission="aa.bb.cc.read"

            android:writePermission="aa.bb.cc.write"

            android:exported="true">

        </provider>

    </application>

 

</manifest>

2 编写实体Person

package com.itheima28.sqlitedemo.entities;

 

publicclass Person {

 

    privateintid;

    private String name;

    privateintage;

    publicint getId() {

       returnid;

    }

    publicvoid setId(int id) {

       this.id = id;

    }

    public String getName() {

       returnname;

    }

    publicvoid setName(String name) {

       this.name = name;

    }

    publicint getAge() {

       returnage;

    }

    publicvoid setAge(int age) {

       this.age = age;

    }

    public Person() {

       super();

       // TODO Auto-generated constructor stub

    }

    public Person(int id, String name, int age) {

       super();

       this.id = id;

       this.name = name;

       this.age = age;

    }

    @Override

    public String toString() {

       return"Person [id=" + id + ", name=" + name + ", age=" + age + "]";

    }

}

3 编写dbHelper

package com.itheima28.sqlitedemo.db;

 

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

import android.util.Log;

 

/**

 * @author toto

 * 数据库帮助类,用于创建和管理数据库的

 */

public class PersonSQLiteOpenHelper extends SQLiteOpenHelper{

         private static final String TAG = "PersonSQLiteOpenHelper";

        

         public PersonSQLiteOpenHelper(Context context){

                   super(context, "itheima28.db", null, 2);

         }

        

         /**

          * 数据库第一次创建时回调此方法

          * 初始化表

          */

         @Override

         public void onCreate(SQLiteDatabase db) {

                   //操作数据

                   String sql = "create table person(_id integer primary key, name varchar(20), age integer);";

                   db.execSQL(sql);

         }

 

         /**

          * 数据库的版本号更新时回调此方法

          * 更新数据库的内容(删除表,添加表,修改表)

          */

         @Override

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

                   if (oldVersion == 1 && newVersion == 2) {

                            Log.i(TAG, "数据库更新啦");

                            db.execSQL("alter table person add balance integer;");

                   }

         }

 

}

4 编写通过sql的Dao操作类

package com.itheima28.sqlitedemo.dao;

 

import java.util.ArrayList;

import java.util.List;

 

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

 

import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper;

import com.itheima28.sqlitedemo.entities.Person;

 

public class PersonDao {

 

         private PersonSQLiteOpenHelper mOpenHelper;   // 数据库的帮助类对象

 

         public PersonDao(Context context) {

                   mOpenHelper = new PersonSQLiteOpenHelper(context);

         }

        

         /**

          * 添加到person表一条数据

          * @param person

          */

         public void insert(Person person) {

                   SQLiteDatabase db = mOpenHelper.getWritableDatabase();

                   if(db.isOpen()) {        // 如果数据库打开, 执行添加的操作

                           

                            // 执行添加到数据库的操作

                            db.execSQL("insert into person(name, age) values(?, ?);", new Object[]{person.getName(), person.getAge()});

                           

                            db.close();        // 数据库关闭

                   }

         }

        

         /**

          * 更据id删除记录

          * @param id

          */

         public void delete(int id) {

                   SQLiteDatabase db = mOpenHelper.getWritableDatabase();         // 获得可写的数据库对象

                   if(db.isOpen()) {        // 如果数据库打开, 执行添加的操作

                           

                            db.execSQL("delete from person where _id = ?;", new Integer[]{id});

                           

                            db.close();        // 数据库关闭

                   }

         }

        

 

         /**

          * 根据id找到记录, 并且修改姓名

          * @param id

          * @param name

          */

         public void update(int id, String name) {

                   SQLiteDatabase db = mOpenHelper.getWritableDatabase();

                   if(db.isOpen()) {        // 如果数据库打开, 执行添加的操作

                           

                            db.execSQL("update person set name = ? where _id = ?;", new Object[]{name, id});

                           

                            db.close();        // 数据库关闭

                   }

         }

        

         public List<Person> queryAll() {

                   SQLiteDatabase db = mOpenHelper.getReadableDatabase();       // 获得一个只读的数据库对象

                   if(db.isOpen()) {

                           

                            Cursor cursor = db.rawQuery("select _id, name, age from person;", null);

                           

                            if(cursor != null && cursor.getCount() > 0) {

                                     List<Person> personList = new ArrayList<Person>();

                                     int id;

                                     String name;

                                     int age;

                                     while(cursor.moveToNext()) {

                                               id = cursor.getInt(0);        // 取第0列的数据 id

                                               name = cursor.getString(1);    // 取姓名

                                               age = cursor.getInt(2);              // 取年龄

                                               personList.add(new Person(id, name, age));

                                     }

 

                                     db.close();

                                     return personList;

                            }

                            db.close();

                   }

                   return null;

         }

        

         /**

          * 根据id查询人

          * @param id

          * @return

          */

         public Person queryItem(int id) {

                   SQLiteDatabase db = mOpenHelper.getReadableDatabase();       // 获得一个只读的数据库对象

                   if(db.isOpen()) {

                            Cursor cursor = db.rawQuery("select _id, name, age from person where _id = ?;", new String[]{id + ""});

                            if(cursor != null && cursor.moveToFirst()) {

                                     int _id = cursor.getInt(0);

                                     String name = cursor.getString(1);

                                     int age = cursor.getInt(2);

                                     db.close();

                                     return new Person(_id, name, age);

                            }

                            db.close();

                   }

                   return null;

         }

}

5 编写不是通过sql的操作类

package com.itheima28.sqlitedemo.dao;

 

import java.util.ArrayList;

import java.util.List;

 

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.util.Log;

 

import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper;

import com.itheima28.sqlitedemo.entities.Person;

 

public class PersonDao2 {

 

         private static final String TAG = "PersonDao2";

         private PersonSQLiteOpenHelper mOpenHelper;   // 数据库的帮助类对象

 

         public PersonDao2(Context context) {

                   mOpenHelper = new PersonSQLiteOpenHelper(context);

         }

        

         /**

          * 添加到person表一条数据

          * @param person

          */

         public void insert(Person person) {

                   SQLiteDatabase db = mOpenHelper.getWritableDatabase();

                   if(db.isOpen()) {        // 如果数据库打开, 执行添加的操作

                           

                            ContentValues values = new ContentValues();

                            values.put("name", person.getName());                  // key作为要存储的列名, value对象列的值

                            values.put("age", person.getAge());

                            long id = db.insert("person", "name", values);

                            Log.i(TAG, "id: " + id);

                           

                            db.close();        // 数据库关闭

                   }

         }

        

         /**

          * 更据id删除记录

          * @param id

          */

         public void delete(int id) {

                   SQLiteDatabase db = mOpenHelper.getWritableDatabase();         // 获得可写的数据库对象

                   if(db.isOpen()) {        // 如果数据库打开, 执行添加的操作

                           

                            String whereClause = "_id = ?";

                            String[] whereArgs = {id + ""};

                            int count = db.delete("person", whereClause, whereArgs);

                            Log.i(TAG, "删除了: " + count + "行");

                            db.close();        // 数据库关闭

                   }

         }

        

         /**

          * 根据id找到记录, 并且修改姓名

          * @param id

          * @param name

          */

         public void update(int id, String name) {

                   SQLiteDatabase db = mOpenHelper.getWritableDatabase();

                   if(db.isOpen()) {        // 如果数据库打开, 执行添加的操作

                            ContentValues values = new ContentValues();

                            values.put("name", name);

                           

                            int count  = db.update("person", values, "_id = ?", new String[]{id + ""});

 

                            Log.i(TAG, "修改了: " + count + "行");

                           

                            db.close();        // 数据库关闭

                   }

         }

        

         public List<Person> queryAll() {

                   SQLiteDatabase db = mOpenHelper.getReadableDatabase();       // 获得一个只读的数据库对象

                   if(db.isOpen()) {

                            String[] columns = {"_id", "name", "age"};     // 需要的列

                            String selection = null;     // 选择条件, 给null查询所有

                            String[] selectionArgs = null;   // 选择条件的参数, 会把选择条件中的? 替换成数据中的值

                            String groupBy = null;       // 分组语句  group by name

                            String having = null; // 过滤语句

                            String orderBy = null;       // 排序

                           

                            Cursor cursor = db.query("person", columns, selection, selectionArgs, groupBy, having, orderBy);

                           

                            int id;

                            String name;

                            int age;

                            if(cursor != null && cursor.getCount() > 0) {

                                     List<Person> personList = new ArrayList<Person>();

                                    

                                     while(cursor.moveToNext()) {  // 向下移一位, 知道最后一位, 不可以往下移动了, 停止.

                                               id = cursor.getInt(0);

                                               name = cursor.getString(1);

                                               age = cursor.getInt(2);

                                              

                                               personList.add(new Person(id, name, age));

                                     }

                                    

                                     db.close();

                                     return personList;

                            }

                            db.close();

                   }

                   return null;

         }

        

         /**

          * 根据id查询人

          * @param id

          * @return

          */

         public Person queryItem(int id) {

                   SQLiteDatabase db = mOpenHelper.getReadableDatabase();       // 获得一个只读的数据库对象

                   if(db.isOpen()) {

                            String[] columns = {"_id", "name", "age"};     // 需要的列

                            String selection = "_id = ?";     // 选择条件, 给null查询所有

                            String[] selectionArgs = {id + ""};     // 选择条件的参数, 会把选择条件中的? 替换成数据中的值

                            String groupBy = null;       // 分组语句  group by name

                            String having = null; // 过滤语句

                            String orderBy = null;       // 排序

                           

                            Cursor cursor = db.query("person", columns, selection, selectionArgs, groupBy, having, orderBy);

                           

                            if(cursor != null && cursor.moveToFirst()) {              // cursor对象不为null, 并且可以移动到第一行

                                     int _id = cursor.getInt(0);

                                     String name = cursor.getString(1);

                                     int age = cursor.getInt(2);

                                    

                                     db.close();

                                     return new Person(_id, name, age);

                            }

                            db.close();

                   }

                   return null;

         }

}

6 编写通过sql操作数据库的单元测试

package com.itheima28.sqlitedemo.test;

 

import java.util.List;

 

import android.database.sqlite.SQLiteDatabase;

import android.test.AndroidTestCase;

import android.util.Log;

 

import com.itheima28.sqlitedemo.dao.PersonDao;

import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper;

import com.itheima28.sqlitedemo.entities.Person;

 

public class TestCase extends AndroidTestCase {

 

         private static final String TAG = "TestCase";

 

         public void test() {

                   // 数据库什么时候创建

                   PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext());

                  

                   // 第一次连接数据库时创建数据库文件. onCreate会被调用

                   openHelper.getReadableDatabase();

         }

        

         public void testInsert() {

                   PersonDao dao = new PersonDao(getContext());

                  

                   for (int i = 0; i < 20; i++) {

                            dao.insert(new Person(0, "冠希" + i, 10 + i));

                   }

         }

        

         public void testDelete() {

                   PersonDao dao = new PersonDao(getContext());

                   dao.delete(1);

         }

 

         public void testUpdate() {

                   PersonDao dao = new PersonDao(getContext());

                   dao.update(3, "凤姐");

         }

 

         public void testQueryAll() {

                   PersonDao dao = new PersonDao(getContext());

                   List<Person> personList = dao.queryAll();

                  

                   for (Person person : personList) {

                            Log.i(TAG, person.toString());

                   }

         }

 

         public void testQueryItem() {

                   PersonDao dao = new PersonDao(getContext());

                   Person person = dao.queryItem(4);

                   Log.i(TAG, person.toString());

         }

        

         public void testTransaction() {

                   PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext());

                   SQLiteDatabase db = openHelper.getWritableDatabase();

                  

                   if(db.isOpen()) {

                            try {

                                     // 开启事务

                                     db.beginTransaction();

                                    

                                     // 1. 从张三账户中扣1000块钱

                                     db.execSQL("update person set balance = balance - 1000 where name = 'zhangsan';");

                                    

                                     // ATM机, 挂掉了.

                                     // int result = 10 / 0;

                                    

                                     // 2. 向李四账户中加1000块钱

                                     db.execSQL("update person set balance = balance + 1000 where name = 'lisi';");

                                    

                                     // 标记事务成功

                                     db.setTransactionSuccessful();

                            } finally {

                                     // 停止事务

                                     db.endTransaction();

                            }

                            db.close();

                   }

         }

        

         public void testTransactionInsert() {

                   PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext());

                   SQLiteDatabase db = openHelper.getWritableDatabase();

                  

                   if(db.isOpen()) {

                           

                            // 1. 记住当前的时间

                            long start = System.currentTimeMillis();

                           

                            // 2. 开始添加数据

                            try {

                                     db.beginTransaction();

                                     for (int i = 0; i < 10000; i++) {

                                               db.execSQL("insert into person(name, age, balance) values('wang" + i + "', " + (10 + i) + ", " + (10000 + i) + ")");

                                     }

                                     db.setTransactionSuccessful();

                            } finally {

                                     db.endTransaction();

                            }

                           

                            // 3. 记住结束时间, 计算耗时时间

                            long end = System.currentTimeMillis();

                           

                            long diff = end - start;

                            Log.i(TAG, "耗时: " + diff + "毫秒");

                           

                            db.close();

                   }

         }

}

7 编写不是通过sql操作的数据库的单元测试

package com.itheima28.sqlitedemo.test;

 

import java.util.List;

 

import android.test.AndroidTestCase;

import android.util.Log;

 

import com.itheima28.sqlitedemo.dao.PersonDao2;

import com.itheima28.sqlitedemo.db.PersonSQLiteOpenHelper;

import com.itheima28.sqlitedemo.entities.Person;

 

public class TestCase2 extends AndroidTestCase {

 

         private static final String TAG = "TestCase";

 

         public void test() {

                   // 数据库什么时候创建

                   PersonSQLiteOpenHelper openHelper = new PersonSQLiteOpenHelper(getContext());

                  

                   // 第一次连接数据库时创建数据库文件. onCreate会被调用

                   openHelper.getReadableDatabase();

         }

        

         public void testInsert() {

                   PersonDao2 dao = new PersonDao2(getContext());

                   dao.insert(new Person(0, "zhouqi", 88));

         }

        

         public void testDelete() {

                   PersonDao2 dao = new PersonDao2(getContext());

                   dao.delete(8);

         }

 

         public void testUpdate() {

                   PersonDao2 dao = new PersonDao2(getContext());

                   dao.update(3, "fengjie");

         }

 

         public void testQueryAll() {

                   PersonDao2 dao = new PersonDao2(getContext());

                   List<Person> personList = dao.queryAll();

                  

                   for (Person person : personList) {

                            Log.i(TAG, person.toString());

                   }

         }

 

         public void testQueryItem() {

                   PersonDao2 dao = new PersonDao2(getContext());

                   Person person = dao.queryItem(4);

                   Log.i(TAG, person.toString());

         }

}

8 Activity不用写东西

 

二、第二个测试项目调用第一个项目的ContentProvider

清单文件如下:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.itheima28.othercontentprovider"

    android:versionCode="1"

    android:versionName="1.0" >

   

    <instrumentation

        android:name="android.test.InstrumentationTestRunner"

        android:targetPackage="com.itheima28.othercontentprovider">

    </instrumentation>

    <uses-permission android:name="aa.bb.cc.read"/>

    <uses-permission android:name="aa.bb.cc.write"/>

   

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="19" />

 

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <uses-library android:name="android.test.runner"/>

       

        <activity

            android:name="com.itheima28.othercontentprovider.MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

 

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

 

</manifest>

2 Activity不用写

3 单元测试类如下:

package com.itheima28.othercontentprovider;

 

import android.content.ContentResolver;

import android.content.ContentUris;

import android.content.ContentValues;

import android.database.Cursor;

import android.net.Uri;

import android.test.AndroidTestCase;

import android.util.Log;

 

publicclass TextCase extends AndroidTestCase {

 

    privatestaticfinal String TAG = "TextCase";

   

    publicvoid testInsert() {

       Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/insert");

      

       //内容提供者访问对象

       ContentResolver resolver = getContext().getContentResolver();

      

       ContentValues values = new ContentValues();

       values.put("name", "fengjie");

       values.put("age", 90);

      

       uri = resolver.insert(uri, values);

       Log.i(TAG, "uri:" + uri);

       long id = ContentUris.parseId(uri);

       Log.i(TAG, "添加到:" + id);

    }

   

    publicvoid testDelete() {

       Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/delete");

      

       //内容提供者访问对象

       ContentResolver resolver = getContext().getContentResolver();

      

       String where = "_id = ?";

       String[] selectionArgs = {"21"};

       int count = resolver.delete(uri, where, selectionArgs);

       Log.i(TAG, "删除行:" + count);

    }

   

    publicvoid testUpdate() {

       Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/update");

   

       //内容提供者访问对象

       ContentResolver resolver = getContext().getContentResolver();

      

       ContentValues values = new ContentValues();

       values.put("name", "lisi");

      

       int count = resolver.update(uri, values,"_id = ?", new String[]{"20"});

       Log.i(TAG, "更新行:" + count);

    }

   

    publicvoid testQueryAll() {

       Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/queryAll");

      

       //内容提供者访问对象

       ContentResolver resolver = getContext().getContentResolver();

       Cursor cursor = resolver.query(uri, new String[]{"_id", "name", "age"}, null, null, "_id desc");

      

       if (cursor != null && cursor.getCount() > 0) {

           int id;

           String name;

           int age;

           while(cursor.moveToNext()){

              id = cursor.getInt(0);

              name = cursor.getString(1);

              age = cursor.getInt(2);

              Log.i(TAG, "id: " + id + ", name: " + name + ", age: " + age);

           }

           cursor.close();

       }

    }

   

    publicvoid testQuerySingleItem() {

       Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/#");

      

       // uri的末尾添加一个id content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/20

       uri = ContentUris.withAppendedId(uri, 20);

      

       //内容提供者访问对象

       ContentResolver resolver = getContext().getContentResolver();

       Cursor cursor = resolver.query(uri, new String[]{"_id", "name", "age"}, null, null, null);

       if (cursor != null && cursor.moveToFirst()) {

           int id = cursor.getInt(0);

           String name = cursor.getString(1);

           int age = cursor.getInt(2);      

           cursor.close();

           Log.i(TAG, "id: " + id + ", name: " + name + ", age: " + age);

       }

    }

}

 

目录
相关文章
|
1月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
114 1
|
1月前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
102 2
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
151 0
安卓项目:app注册/登录界面设计
|
2月前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
20天前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
在 Android 开发中,选择合适的架构模式对于构建中大型项目至关重要。常见的架构模式有 MVVM、MVP、MVI、Clean Architecture 和 Flux/Redux。每种模式都有其优缺点和适用场景,例如 MVVM 适用于复杂 UI 状态和频繁更新,而 Clean Architecture 适合大型项目和多平台开发。选择合适的架构应考虑项目需求、团队熟悉度和可维护性。
48 6
|
30天前
|
前端开发 JavaScript 测试技术
Android适合构建中大型项目的架构模式全面对比
Android适合构建中大型项目的架构模式全面对比
46 2
|
2月前
|
Java Maven 开发工具
第一个安卓项目 | 中国象棋demo学习
本文是作者关于其第一个安卓项目——中国象棋demo的学习记录,展示了demo的运行结果、爬坑记录以及参考资料,包括解决Android Studio和maven相关问题的方法。
第一个安卓项目 | 中国象棋demo学习
|
1月前
|
编译器 Android开发
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
|
2月前
|
JavaScript 前端开发 Android开发
让Vite+Vue3项目在Android端离线打开(不需要起服务)
让Vite+Vue3项目在Android端离线打开(不需要起服务)
|
2月前
|
IDE 开发工具 Android开发
安卓与iOS开发对比:平台选择对项目成功的影响
【9月更文挑战第10天】在移动应用开发的世界中,选择正确的平台是至关重要的。本文将深入探讨安卓和iOS这两大主要移动操作系统的开发环境,通过比较它们的市场份额、开发工具、编程语言和用户群体等方面,为开发者提供一个清晰的指南。我们将分析这两个平台的优势和劣势,并讨论如何根据项目需求和目标受众来做出最佳选择。无论你是初学者还是有经验的开发者,这篇文章都将帮助你更好地理解每个平台的特性,并指导你做出明智的决策。