精华内容
下载资源
问答
  • android App 架构模式: Android 原生开发知识体系: 操作系统知识体系:

     android App 架构模式:

     

    Android 原生开发知识体系:

     

    操作系统知识体系:

    展开全文
  • 原生Android_APP目录结构分析

    千次阅读 2020-01-20 10:26:12
    结构图中可以看到, 该工程下面有两个目录: 一个是app, 另一个是Gradle Scripts。 其中, app下面又 有3个子目录, 功能说明如下: (1) manifests子目录, 下面只有一个xml文件, 即AndroidManifest.xml, 是...

    1 App工程目录

     

    从结构图中可以看到, 该工程下面有两个目录: 一个是app, 另一个是Gradle Scripts。 其中, app下面又
    有3个子目录, 功能说明如下:
    (1) manifests子目录, 下面只有一个xml文件, 即AndroidManifest.xml, 是App的运行配置文件。
    (2) java子目录, 下面有3个com.example.hellorworld包, 其中第一个包存放的是App工程的java源代
    码, 后面两个包存放的是测试用的Java代码。
    (3) res子目录, 存放的是App工程的资源文件。 res子目录下又有4个子目录:
    drawable目录存放的是图形描述文件与用户图片。
    layout目录存放的是App页面的布局文件。
    mipmap目录存放的是启动图标。
    values目录存放的是一些常量定义文件, 比如字符串常量strings.xml、 像素常量dimens.xml、 颜色常量
    colors.xml、 样式风格定义styles.xml等。
    Gradle Scripts下面主要是工程的编译配置文件, 主要有:
    (1) build.gradle, 该文件分为项目级与模块级两种, 用于描述App工程的编译规则。
    (2) proguard-rules.pro, 该文件用于描述java文件的代码混淆规则。
    (3) gradle.properties, 该文件用于配置编译工程的命令行参数, 一般无须改动。
    (4) settings.gradle, 配置哪些模块在一起编译。 初始内容为include ':app', 表示只编译App模块。
    (5) local.properties, 项目的本地配置, 一般无须改动。 该文件是在工程编译时自动生成的, 用于描述
    开发者本机的环境配置, 比如SDK的本地路径、 NDK的本地路径等。

    2 编译配置文件build.gradle

    apply plugin: 'com.android.application'
    ​
    android {
        // 指定编译的SDK版本号 如29表示Android 10 编译
        compileSdkVersion 29
        // 指定编译工具的版本号,这里的头两位数字必须与compileSdkVersion 保持一致,具体的版本号可在sdk安装目录的"sdk\build-tools"下找到
        buildToolsVersion "29.0.2"
        defaultConfig {
            // 指定该模块的应用编号,即App的包名。该参数为自动生成,无需修改
            applicationId "com.example.hellodemo"
            // 指定App适合运行的最小SDK版本号。如16表示至少要在Android4.1上运行
            minSdkVersion 16
            // 指定目标设备的SDK版本号。即该App最希望在哪个版本的Android上运行
            targetSdkVersion 29
            // 指定App的应用版本号
            versionCode 1
            // 指定App的应用版本名称
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                // 指定是否开启代码混淆功能。true表示开启混淆,false表示无需混淆。
                minifyEnabled false
                // 指定代码混淆规则的文件名
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    }
    ​
    // 指定App编译的依赖信息
    dependencies {
        // 指定引用jar包的路径
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        // AndroidX是Google 2018 IO 大会推出的新扩展库  与支持库不同,AndroidX 软件包会单独维护和更新。       androidx 软件包使用严格的语义版本控制,从版本 1.0.0 开始,可以单独更新项目中的 AndroidX 库
        implementation 'androidx.appcompat:appcompat:1.0.2'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
        // 指定单元测试的Junit版本
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.0'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    }
    ​

    3 AndroidX

    3.1 Androidx是什么

    AndroidX 是 Android 团队用于在 Jetpack 中开发、测试、打包和发布库以及对其进行版本控制的开源项目。[摘自官方]
    AndroidX完全取代了支持库,不仅提供同等的功能,而且提供了新的库。
    AndroidX 会将原始支持库 API 软件包映射到 androidx 命名空间。只有软件包和 Maven 工件名称发生了变化;类、方法和字段名称没有改变。
    与支持库不同,AndroidX 软件包会单独维护和更新。androidx 软件包使用严格的语义版本控制,从版本 1.0.0 开始,可以单独更新项目中的 AndroidX 库。
    所有新支持库的开发工作都将在 AndroidX 库中进行,这包括维护原始支持库工件和引入新的 Jetpack 组件。

    3.2 AndroidX的变化

    1.常见依赖库映射

    旧编译工件AndroidX 编译工件
    com.android.support.constraint:constraint-layoutandroidx.constraintlayout:constraintlayout:1.1.2
    com.android.support:appcompat-v7androidx.appcompat:appcompat:1.0.0
    com.android.support:cardview-v7androidx.cardview:cardview:1.0.0
    com.android.support:coordinatorlayoutandroidx.coordinatorlayout:coordinatorlayout:1.0.0
    com.android.support:designcom.google.android.material:material:1.0.0-rc01
    com.android.support:drawerlayoutandroidx.drawerlayout:drawerlayout:1.0.0
    com.android.support:gridlayout-v7androidx.gridlayout:gridlayout:1.0.0
    com.android.support:media2androidx.media2:media2:1.0.0-alpha03
    com.android.support:multidexandroidx.multidex:multidex:2.0.0
    com.android.support:percentandroidx.percentlayout:percentlayout:1.0.0
    com.android.support:recyclerview-v7androidx.recyclerview:recyclerview:1.0.0
    com.android.support:support-annotationsandroidx.annotation:annotation:1.0.0
    com.android.support:support-compatandroidx.core:core:1.0.0
    com.android.support:support-fragmentandroidx.fragment:fragment:1.0.0
    com.android.support:support-v4androidx.legacy:legacy-support-v4:1.0.0
    com.android.support:viewpagerandroidx.viewpager:viewpager:1.0.0
    com.android.support:swiperefreshlayoutandroidx.swiperefreshlayout:swiperefreshlayout:1.0.0

    更多详细依赖库变化,可查阅官方文档或下载这些映射的 CSV 格式文件。

    2.常见类映射

    支持库类AndroidX 类
    android.arch.lifecycle.Lifecycleandroidx.lifecycle.Lifecycle
    android.support.v4.app.Fragmentandroidx.fragment.app.Fragment
    android.support.v4.app.FragmentActivityandroidx.fragment.app.FragmentActivity
    android.support.v7.app.AppCompatActivityandroidx.appcompat.app.AppCompatActivity
    android.support.v7.app.ActionBarandroidx.appcompat.app.ActionBar
    android.support.v7.widget.RecyclerViewandroidx.recyclerview.widget.RecyclerView
    android.support.design.card.MaterialCardViewcom.google.android.material.card.MaterialCardView
    android.support.design.ripple.RippleUtilscom.google.android.material.ripple.RippleUtils
    android.support.design.widget.CoordinatorLayoutandroidx.coordinatorlayout.widget.CoordinatorLayout
    android.support.design.widget.NavigationViewcom.google.android.material.navigation.NavigationView
    android.support.percent.PercentFrameLayoutandroidx.percentlayout.widget.PercentFrameLayout

    更多详细支持类映射变化,可查阅官方文档或下载这些映射的 CSV 格式文件。

    3.3 为什么要迁移AndroidX?

    下面是Google官方描述

    Existing packages, such as the Android Support Library, are being refactored into AndroidX.
    Although Support Library versions 27 and lower are still available on Google Maven,
    all new development will be included in only AndroidX versions 1.0.0 and higher.
    • 大致意思是:现有的软件包,如Android支持库,正在被重构为Androidx。尽管在Google Maven上仍然提供支持库版本27及更低版本,但所有新开发将只包含在Androidx 1.0.0及更高版本中。

    展开全文
  • Android(三)原生开发基本知识

    千次阅读 2020-05-29 03:58:25
    2、打开Android Studio(环境搭建,目录结构讲解),新建一个项目,选择项目类型,一般可选的有: 这里的Activity就相当于MVC中的controller,跳转到Activity后,Activity会加载布局文件layout进来并渲染,最后展示...

    一、基本认识

    1、目的:实现业务逻辑,生成可用apk


    2、打开Android Studio(环境搭建目录结构讲解),新建一个项目,选择项目类型,一般可选的有:

    新建项目类型
    这里的Activity就相当于MVC中的controller,跳转到Activity后,Activity会加载布局文件layout进来并渲染,最后展示在屏幕上,所以新建项目会提供一些Activity模板供选择。

    • 其中有个Empty Activity,也就是新建一个空的Activity,但是不创建对应的layout文件,所以页面是空白的。
    • Login Activity,会创建对应的登录逻辑代码,并且配置一个登陆页面的layout,实现了登录页面和登录逻辑的基本功能。
    • 其他Activity同理。

    这里我选择了No Activity,也就是只是一个项目,但是没有任何的Activity页面,全部自己创建。
    我选择的Min API是23,安卓sdk有对应版本的,安卓6就是对应API-23,安卓10对应API-29,我这里支持最小安卓6(API-23)版本,但是我的项目的编译目标版本是API-29。

    同时,我不勾选use legacy android support library,意思就是我不需要使用到android support library这个类库的支持,

    这么说吧,安卓6版本自带了API-23的所有类库,就跟jdk一样的原理,但是如果需要使用API-23外的其他类,则需要引入对应的类库,比如android support library是额外的支持库,support-v4和appcompat-v7就是android support library的其中两个版本,
    但是安卓后来把这些额外类库统一调整并命名到androidx这个包路径下,作为一个第三方标准类库供引入来开发,需要编译版本达到API-28才能使用(最低版本不需要达到),由于这是趋势,所以最好使用。


    3、先借助一个写好的项目说明下项目各个配置是怎样的:

    比如项目结构截图如下:
    项目根目录结构

    • 先说图中的1,settings.gradle文件,指定项目名称,include ':app'好像表示会打包成一个app而不是一个依赖库,依赖库就是给其他项目引用的。
    rootProject.name='项目名称'
    include ':app'
    
    • 图中2,gradle.properties文件,配置运行环境参数比如最大堆内存等。android.useAndroidX=trueandroid.enableJetifier=true表示自动使用androidx依赖库,如果使用到对应的类会自动引入androidx依赖包
    org.gradle.jvmargs=-Xmx1536m
    
    # AndroidX package structure to make it clearer which packages are bundled with the
    # Android operating system, and which are packaged with your app's APK
    android.useAndroidX=true
    
    # Automatically convert third-party libraries to use AndroidX
    android.enableJetifier=true
    
    
    • 图中3,External Libraries,下面是当前项目的所有引用,可以从这里看到所有依赖jar。
    • 图中4,build.gradle文件,在项目的根目录下,如下,是关于从哪里下载依赖,以及一些项目级别的配置:
    
    buildscript {
        repositories {
            google()
            jcenter()
            
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.6.3'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
    
    • 图中的gradlebuild.idea.gradle文件夹,这些是idea以及外部环境如何定义当前项目,一般跟项目代码无关,可以不关注。
    • 图中5,app,这个是项目核心目录,所有安卓app的配置、资源和源代码都是放在这个目录下的,我单独把这个目录拿出来。

    app目录截图如下:
    app目录截图

    • 图中1,build目录,这个目录是项目编译后放字节码文件,重新编译前可以直接删掉没事。
    • 图中2,libs目录,存放依赖的jar包,放在这个目录的jar会自动添加到依赖(加上依赖就行:implementation fileTree(dir: 'libs', include: ['*.jar'])
    • 图中3,releas目录,存放build->generate sign/ apk选项生成的apk文件。
    • 图中4,build.gradle文件,区别于项目根目录的同名那个文件,app下的这个是
      指定编译版本,运行最低版本,发布版本,以及所有dependencies,如下,把libs下所有jar关联,然后导入了很多androidx的依赖:
    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 29
        buildToolsVersion '29.0.3'
    
        defaultConfig {
            applicationId "com.lwr.password"
            minSdkVersion 23
            targetSdkVersion 29
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    
        implementation 'androidx.appcompat:appcompat:1.1.0'
        implementation 'com.google.android.material:material:1.1.0'
        implementation 'androidx.annotation:annotation:1.1.0'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
        implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
        implementation 'androidx.legacy:legacy-support-v4:1.0.0'
        implementation 'androidx.navigation:navigation-fragment:2.2.2'
        implementation 'androidx.navigation:navigation-ui:2.2.2'
    
        implementation 'com.github.bumptech.glide:glide:4.11.0' /*手势密码*/
        annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'/*手势密码*/
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.1'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    }
    
    
    • 图中5, src\main\java,这是源码目录,存放所有源码,也就是java类。
    • 图中6, src\main\res,资源目录,存放图片,样式,布局文件layout,等等。

    • 图中7,src\main\AndroidManifest.xml文件,相当于web.xml文件,
    1. package="com.lwr.password"配置app基础路径,作为其他相对路径的base。
    2. <uses-permission配置需要用到的权限,比如读写权限,安装apk时候可以看到,但是启动app时候具体权限还要一个个申请。
    3. <application android:name=".MyApplication"这里的MyApplication是我自定义的一个继承Application的类,在android:name配置之后这个类会在启动时被初始化。
    4. 然后是所有的Activity都要在此声明,否则不可跳转。其中选择一个Activity配置android.intent.category.LAUNCHERmain作为第一个看到的页面,如下:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.lwr.password">
        <!-- 读写权限 -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
        <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:requestLegacyExternalStorage="true"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".ui.userupdate.RegisterActivity"></activity>
            <activity
                android:name=".activity.SplashActivity"
                android:theme="@style/TransparentTheme">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name=".ui.gesture.PwdGestureActivity"
                android:theme="@style/TransparentTheme" />
            <activity
                android:name=".ui.gesture.PwdGestureCheckActivity"
                android:theme="@style/TransparentTheme" />
            <activity
                android:name=".ui.login.LoginActivity"
                android:label="@string/app_name"
                android:theme="@style/AppTheme.NoActionBar" />
            <activity
                android:name=".MainActivity"
                android:label="@string/title_activity_main"
                android:theme="@style/AppTheme.NoActionBar"></activity>
    
            <activity
                android:name=".filechooser.FileChooserActivity"
                android:exported="true"
                android:label="选择文件"
                android:theme="@style/AppTheme.NoActionBar">
                <intent-filter>
                    <action android:name="android.intent.action.GET_CONTENT" />
    
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.OPENABLE" />
    
                    <data android:mimeType="*/*" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    

    二、基本操作解析

    下面,一个个来说明使用android studio开发安卓项目,原生开发中的基本操作:


    1、新建Activity

    1、可以通过在包路径上右键,new,选择activity类型,如图:
    在这里插入图片描述
    2、或者直接手动创建一个java类,必须继承Activity或其子类,重新onCreate方法,调用父类onCreate,设置对应的视图为R.layout.layout_activity_my

    public class MyActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_activity_my);
        }
    }
    
    • 同时创建一个layout_activity_my.xml文件:
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MyActivity">
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    启动app后,可以看到这个activity了,但是layout是空的,也就是只有一张背景。

    2、如何创建资源和如何引用资源

    如上面1中代码setContentView(R.layout.layout_activity_my),
    R.layout.layout_activity_my引用的文件在哪?
    这里的R表示的是什么?
    其他不同类型的文件如何创建和引用呢?


    1、先说R,

    其实R是一个虚拟的自动生成的R.java文件public final class com.lwr.password.R,它是当前类连接其他资源的桥梁:

    //引入R类
    import com.lwr.projecname.R;
    

    如果把R理解为class,那么R点后面跟的就是class下的属性,比如R.layou或者R.id等,可以点出来的内容大概有如下:
    R类

    • 乍一看似曾相识,没错,这些是res资源目录下的我文件夹名称,也即是说安卓把res资源当成了属性或者对象。

    • 那么不难理解,如果你使用R.layout.layout_activity_my实际上就是引用res/layout/layout_activity_my.xml这个文件,而用R.drawable.button_drawable就是引用了res\drawable\button_drawable.xml这个文件,这里并不指定必须是xml类型,其他类型比如图片jpg一样能引用。

    • 这里需要说明几个点:

    1)、R是引用R路径下的res资源,比如上面我这个项目指定了package="com.lwr.password",那么通过com.lwr.password.R只能够引用当前app的res资源,所以,
    如下图:
    androidx.appcompat
    如果想要引用package为androidx.appcompat下的res资源,则可以通过androidx.appcompat.R.drawable.abc_vector_test来引用一个资源文件
    (说下,apk安装后,会创建一个名为com.lwr.password的文件夹存放当前app数据,所以package可以理解为资源的目录)

    2)、R.id.资源ID返回的是已给int,表示对应ID的资源内容的引用,比如:

    <?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="@dimen/nav_header_height">
    
        <ImageView
            android:id="@+id/imageViewId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/nav_header_desc"
            android:paddingTop="@dimen/nav_header_vertical_spacing"
            app:srcCompat="@mipmap/ic_launcher_round" />
    
    </LinearLayout>
    

    在layout目录下的一个layout文件,里面定义了一个ImageView元素,指定其ID为imageViewId,那么就可以通过此id来找到这个元素。

    3)、如下Java代码所示:

    ImageView imageView = findViewById(R.id.imageViewId)
    

    如何理解xml文件中的<ImageView>节点呢?你以为它只是一个节点,其实它是一个类:

    @RemoteView
    public class ImageView extends View {
        private static final String LOG_TAG = "ImageView";
    //其他代码
    }
    

    那么android:layout_width="wrap_content",不难理解,layout_width不过是ImageView类的一个属性,所以,就可以把资源和代码联系起来,完全可以自己创建一个继承View的java类,然后把它当成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="@dimen/nav_header_height">
    
        <com.lwr.password.ThisIsMyImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    </LinearLayout>
    

    4)、根据3),可以认识到,就算完全不需要xml文件,完全可以通过代码创建一个视图对象,然后设置它的宽高等属性,还可以给它添加监听事件,然后设置到Activity中渲染显示。

    5)、同样的,除了java代码引用资源对象,也有xml文件需要引用资源的时候,比如设置背景图片:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="@dimen/nav_header_height"
        anandroid:background="@drawable/bg_image">
    
    </LinearLayout>
    

    @drawable/bg_image就是res/drawable目录下的bg_image.jpg或者png图片

    2、资源分类

    回到上面的问题:其他不同类型的文件如何创建和引用呢?
    直接说创建和引用吧:

    1. mipmap-*系列,存放不同尺寸的同名图片,会根据屏幕情况选择展示,创建不同尺寸的图片并放到mipmap目录下,然后通过代码方式:R.mipmap.ic_launcher或者xml方式android:icon="@mipmap/ic_launcher"来引用,这两种引入方式下同,不再赘述。
    2. values:在res/values目录的一个xml文件中,在根节点<resources>
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="prompt_password">密码</string>
        <!--或者-->
        <color name="colorPrimary">#6200EE</color>
        <!--或者-->
        <style name="AppTheme.NoActionBar">
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
        </style>
         <dimen name="nav_header_height">50dp</dimen >
    </resources>
    

    看下面如何引用上面:

    <?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="@dimen/nav_header_height"
        android:background="@color/colorPrimary"
         android:theme="@style/AppTheme.NoActionBar"
        >
    
        <com.lwr.password.TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/prompt_password"
            />
    
    </LinearLayout>
    
    1. 创建资源对象,在res目录右键,创建:
      在这里插入图片描述
      对于不同类型,又有不同的根节点可选,比如layout,可以选LinerLayout线性布局或者其他,比如drawable类型的根节点可以有:
      在这里插入图片描述drawable
      找一个selector的例子说一下:
      drawable/button_abc.xml如下
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="false" android:drawable="@drawable/icon_add1"/>
        <item android:state_pressed="true" android:drawable="@drawable/icon_add"/>
    </selector>
    

    如果在一个按钮的背景引用了这个selector:

    <androidx.appcompat.widget.AppCompatButton
                android:id="@+id/add_id"
                android:layout_width="40dp"
                android:layout_height="30dp"
                android:layout_margin="5dp"
                android:background="@drawable/button_abc"
                />
    

    可知,会根据state_pressed按钮按下的状态显示不同的图片。

    3、页面跳转和回调、页面销毁

    1、跳转

    //MainActivity
    		Intent intent = new Intent(MainActivity.this, MyActivity.class);
            intent.putExtra("yourName", "林雪真");
            intent.putExtra("isTrue", false);
            int requestCode = 999;
            startActivityForResult(intent, requestCode);
    

    上面代码实现从MainActivity跳转到MyActivityIntent最为常用于启动一个activity并与之通信。startActivityForResult和使用startActivity(intent);效果一样,startActivity默认requestCode=-1,最终跑的是同个方法,如果使用requestCode必须大于0,记住不要使用finish()方法。
    跳转到MyActivity后,在onCreate方法中可以通过:

    boolean isTrue  = getIntent().getBooleanExtra("isTrue", false);
    String yourName= getIntent().getStringExtra("yourName");
    

    获取到前者的信号,同样,当执行完毕需要关闭页面,可以向之前页面回传数据:

    //MyActivity
    				//数据是使用Intent返回
                    Intent intent = new Intent();
                    //把返回数据存入Intent
                    intent.putExtra("myName", "My name is 雪");
                    //设置返回数据
                    MyActivity.this.setResult(RESULT_OK + 999, intent);
                    //关闭Activity
                    MyActivity.this.finish();
    

    后者activity回到前者不要用startActivityForResult,startActivity方法会启动一个新的页面,从而数据丢失了。后者直接调用finish()关闭当前页面,finish()大概是把当前页面从页面栈中弹出,从而让上一个页面展示出来,直接就回到上一个页面。

    如果想要获取传回来的数据,需要重写activity的onActivityResult方法,内部执行自己的逻辑,如下:

        @Override
        public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            if (requestCode == 999) {//确认过眼神,requestCode一样,你是我的回调
                if(998 == resultCode){
                    //你告诉我一切都好
                    //看看你姓甚名谁
                    System.out.println(data.getStringExtra("myName"));
                }
            }
            super.onActivityResult(requestCode, resultCode, data);
        }
    

    2、生命周期,页面销毁
    这里其实说的是activity的生命周期。
    先看个生命周期图:
    生命周期图

    • onCreate:加载后台资源,完成一些业务逻辑,页面还没渲染出来。它对应onDestroy,onDestroy会销毁回收占用的资源。
    • onResumeonPause是暂停和恢复当前页面,只是可不可见的问题,实际上页面对象一直存在并未销毁。
    • finish:执行完毕当前业务逻辑后,调用onDestroy,所以整个页面没了。

    4、activity、fragment、view等等之间的关系

    activity是主页面,Fragment是标签页面,而view是视图(可以触摸的那种),与前两者不同。

    • activity中加载页面:
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    		//直接使用findViewById
            Toolbar toolbar = findViewById(R.id.toolbar);
            
    		how(getApplicationContext(),MainActivity.this);
        }
        
        void how(Context context, Activity activity) {
            
        }
    }
    

    Fragment中加载页面

    public class HomeFragment extends Fragment {
    
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            //使用inflater来渲染布局
            View root = inflater.inflate(R.layout.fragment_home, container, false);
            //使用已有的View来查找对应的元素
            final TextView textView = root.findViewById(R.id.text_home);
    
        	how(getContext(), getActivity());
            return root;
        }
        
        void how(Context context, Activity activity) {
            
        }
    }
    

    注意到上面获取Context context, Activity activity这两个参数,activity和Fragment是不一样的,Activity 继承于Context ,它可以直接获取到context和activity,而Fragment是被activity创建的,Fragment需要找到关联的activity之后才能获取到context和activity。

    • fragment应该使用FragmentManager进行管理:
    
            FragmentManager supportFragmentManager = getSupportFragmentManager();
            Fragment nav_host_fragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
            //因为nav_host_fragment内部又套了一层标签页
            FragmentManager childFragmentManager = nav_host_fragment.getChildFragmentManager();
            Fragment 当前标签页 = childFragmentManager.getPrimaryNavigationFragment();
    

    5、安卓中的各种监听事件

    监听事件,建立在能触发事件的组件上,而View组件就能被触发各种事件。
    比如大家都有的点击事件。比如输入改变事件,各种状态改变事件。
    各种事件监听器
    监听Listener的实现:
    第一种,传一个OnClickListener接口的实现类,这里使用匿名内部类:

            final View btn = findViewById(R.id.btn);
            
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    System.out.println(v == btn);//true
                }
            });
    

    第二种,当前类实现OnClickListener接口,直接重写onClick 方法:
    (好处是能拿到this的所有对象资源和方法调用)

    public class Main2Activity extends AppCompatActivity implements View.OnClickListener{
    
        View btn;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
    
            btn = findViewById(R.id.btn);
    
            btn.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            System.out.println(v == btn);//true
        }
    }
    

    第三种:

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="按钮"
    		android:onClick="onButtonClick"
            android:id="@+id/btn"/>
    
    public class Main2Activity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
        }
    
        public void onButtonClick(View view) {
    
        }
    }
    
    
    展开全文
  • 山东APP开发公司中扬科技浅谈APP原生开发、H5开发与APP混合开发三者之间区别 目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合... 一、APP原生开发 原生开发(Native App开发),是在Android、IOS等移...

    山东APP开发公司中扬科技浅谈APP原生开发、H5开发与APP混合开发三者之间区别

    1099d92190124c78661fde4d9427f9a1.png

    目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合APP三种,相对应的定制开发就是原生开发、H5开发和混合开发。那么这三种开发模式究竟有何不同呢?下面我们就分别从这三者各自的优劣势来区分比较吧!

    一、APP原生开发

    原生开发(Native App开发),是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App软件开发。比如Android是利用Java、Eclipse、Android studio;IOS是利用Objective-C 和Xcode进行开发。

    通俗点来讲,原生开发就像盖房子一样,先打地基然后浇地梁、房屋结构、一砖一瓦、钢筋水泥、电路走向等,都是经过精心的设计。原生APP也一样:通过代码从每个页面、每个功能、每个效果、每个逻辑、每个步骤全部用代码写出来,一层层,一段段全用代码写出来。

    优点:

    1、可访问手机所有功能(如GPS、摄像头等)、可实现功能最齐全;

    2、运行速度快、性能高,绝佳的用户体验;

    3、支持大量图形和动画,不卡顿,反应快;

    4、兼容性高,每个代码都经过程序员精心设计,一般不会出现闪退的情况,还能防止病毒和漏洞的出现;

    5、比较快捷地使用设备端提供的接口,处理速度上有优势。

    缺点:

    1、开发时间长,快则3个月左右完成,慢则五个月左右;

    2、制作费用高昂,成本较高;

    3、可移植性比较差,一款原生的App,Android和IOS都要各自开发,同样的逻辑、界面要写两套;

    4、内容限制(App Store限制);

    5、获得新版本时需重新下载应用更新。

    二、Web APP (HTML5)开发

    HTML5应用开发,是利用Web技术进行的App开发。Web技术本身需要浏览器的支持才能进行展示和用户交互,因此主要用到的技术是HTML5、JavaScript、CSS等。

    优点:

    1、支持设备范围广,可以跨平台,编写的代码可以同时在Android、IOS、Windows上运行;

    2、开发成本低、周期短;

    3、无内容限制;

    4、适合展示有大段文字(如新闻、攻略等),且格式比较丰富(如加粗,字体多样)的页面;

    5、用户可以直接使用最新版本(自动更新,不需用户手动更新)。

    缺点:

    1、由于Web技术本身的限制,H5移动应用不能直接访问设备硬件和离线存储,所以在体验和性能上有很大的局限性;

    2、对联网要求高,离线不能做任何操作;

    3、功能有限;

    4、APP反应速度慢,页面切换流畅性较差;

    5、图片和动画支持性不高;

    6、用户体验感较差;

    7、无法调用手机硬件(摄像头、麦克风等)。

    三、混合APP开发(原生+H5)

    混合开发(Hybrid App开发),是指在开发一款App产品的时候,为了提高效率、节省成本而利用原生与H5的开发技术的混合应用。通俗点来说,这就是网页的模式,通常由“HTML5云网站+APP应用客户端”两部份构成。

    混合开发是一种取长补短的开发模式,原生代码部分利用Web View插件或者其它框架为H5提供容器,程序主要的业务实现、界面展示都是利用与H5相关的Web技术进行实现的。比如京东、淘宝、今日头条等APP都是利用混合开发模式而成的。

    优点:

    1、开发效率高,节约时间。同一套代码Android和IOS基本上都可使用;

    2、更新和部署比较方便,每次升级版本只需要在服务器端升级即可,不再需要上传到App Store进行审核;

    3、代码维护方便、版本更新快,节省产品成本;

    4、比web版实现功能多;

    5、可离线运行。

    缺点:

    1、功能/界面无法自定:所有内容都是固定的,不能换界面或增加功能;

    2、加载缓慢/网络要求高:混合APP数据需要全部从服务器调取,每个页面都需要重新下载,因此打开速度慢,网络占用高,缓冲时间长,容易让用户反感;

    3、安全性比较低:代码都是以前的老代码,不能很好地兼容最新手机系统,且安全性较低,网络发展这么快,病毒这么多,如果不实时更新,定期检查,容易产生漏洞,造成直接经济损失;

    4、既懂原生开发又懂H5开发的高端人才难找。

    以上就是原生开发、H5开发和混合开发各自的优缺点。相比之下,由于现代人的个性化需求越来越明显,所以原生APP开发也越来越多,定制化的服务更能满足消费者的需求。若您也想要定制一款别开生面的APP,就来找我们吧!

    758a4522c23d601f031ec85fb0e83241.png

    APP程序开发容易被忽视的两个点:

    产品是第一位

    你必须意识到的一件事是,重要的不是你花了多少钱,而是你要打造的产品有多棒。

    Instagram在不到一年的时间里以10亿美元的价格售出。他们花了大约25万美元建造了一个原型机。与退出价值相比,成本是5万美元还是50万美元没有区别。

    重要的是他们已经建立了一个成功的产品。你可以省下5万美元,但如果这意味着制造一种劣质产品只会给你带来损失,那又有什么用呢?

    换句话说,金钱固然重要,但产品是第一位的。

    设计的实际成本

    不管你的技术有多好。如果你的设计很糟糕,没有人会使用你的APP应用程序。

    我们必须清楚,设计和你的技术一样重要。它是用户看到和与之交互的东西。这是你的应用程序的卖点,也是它背后的理念。

    最终,这也是促使他们注册并长期使用这款应用的原因。

    设计是解决用户问题的关键。如果你想创建一个盈利的应用程序,你就必须在产品开发的这一方面和技术方面都做到最好。

    c377190a140169f9704b9565c1c83a3c.png

    以上就是app程序开发-app原生开发与app混合开发区别全文,希望对大家有所帮助!

    展开全文
  • 移动端app开发,原生开发与混合开发的区别

    万次阅读 多人点赞 2019-09-26 18:47:01
    目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合APP三种,相...原生开发(Native App开发),是在Android、IOS等移动平台上利用提供的开发语言、开发类库、开发工具进行App软件开发。比如Android是...
  • uniapp安卓原生插件开发流程

    千次阅读 热门讨论 2020-12-16 14:10:05
    文章目录记录下uni原生插件开发流程一、准备开发环境二、开发过程2.读入数据总结 记录下uni原生插件开发流程 看官方文档看的有点头蒙 特此记录下 官方文档链接 一、准备开发环境 JAVA环境 jdk1.8 Android Studio ...
  • 前言 找工作还是需要大家不要紧张,有我们干这一行的接触人本来就不多 难免看到面试官会紧张,主要是因为怕面试官问的问题到不上来,那时候不要着急 ,答不上了的千万...想要成为一名优秀的Android开发,你需要一份完备
  • 一、环境搭建 1、安装最新版的Android ...NDK 是 Native Development Kit 的缩写,是 Android 的工具开发包。 作用是快速开发 C/C++ 的动态库,并自动将动态库与应用一起打包到 apk。 CMake是一个跨平台的安装(编译)
  • 很多人说Android开发前景越来越差了 我觉得这个回答是片面的 首先Android应用开发前景差是在最近两年出现的,也就是从2018开始,从那时起移动端的程序员已经慢慢出现供大于求的局面,本人作为移动端开发,深知这一点...
  •  由于工作原因,由Android原生开发转向React Native开发,ReactNative是从去年5月份开始至今,最近公司想要使用Android+H5开发,在这里,找了一篇文章,说一下Android 原生开发、H5、React-Native开发特点。...
  • Android_PDA开发介绍

    2018-01-04 16:48:09
    Android Studio 安装及界面配置 Android Studio 工程目录结构 Android Studio 界面功能及基本操作
  • 一、Android 个人手机通讯录开发 数据存储:SQLite 数据库 开发工具:Android Studio 二、Phone Module 简介 1. 界面展示 2. 文件结构简单分析 三、个人手机通讯录代码实现 1. 清单文件 (AndroidManifest.xml) &...
  • 嵌入原生View-Android 嵌入原生View-IOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生通信-EventChannel 添加 Flutter 到 Android Activity 添加 Flutter 到 Android Fragment 添加 Flutter 到 ...
  • Android原生项目集成flutter项目混合开发 方案挑选: 目前主要有两种集成方式: 1、源码集成:就是谷歌官方提供的方案( https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps ) 2、 产物集成: ...
  • 前言 ...作为一个 web 开发,HTTP 几乎是天天要打交道的东西,但我发现大部分人对 HTTP 只是浅尝辄止,对更多的细节及原理就了解不深了,在面试的时候感觉非常吃力。这篇文章就是为了帮助...Android View绘制流程,当一
  • 安卓系统结构安卓开发目录结构

    万次阅读 2018-09-12 10:04:15
    由于安卓的系统架构说起来很抽象,所以博主画了一张图来帮助大家了解结构 Android系统架构 1、 Linux内核 安卓的运行并不是凭空而来的,而是依赖于Linux内核之上,因此,内核就显得极为重要,没有了内核就像折...
  • 开头 今天在浏览技术新闻的时候,发现腾讯就在今天开源了一套...这个开源框架就是:QMUI_Android ,它的 Slogan 是:提高 Android UI 开发效率的 UI 库。 QMUI Android 的设计目的是用于辅助快速搭建一个具备基本设计还
  • 最近工作中接触到React-Native框架,对其进行一些技术分析,结合之前了解的H5的一部分,加上自己做了很久的原生开发(十几个android app、sdk,包括2个ios), 总结下目前了解到的这三种移动端应用开发方式的特点和...
  • 数据结构算法,调优,View,SDK**,**动画音视频等以及你使用过的框架且第一轮的基础很重要,通过后录取可能性就相对高了! 金三银四已经到了,在这也免费分享一些Java程序员面试常问架构面试专题和答案以及架构视频...
  • 前言 记得去年9月份的...于是尝试在公司找个小项目上马,进行混合开发试试。 方案选择 目前主流的混合开发方案有两种集成方式:源码集成 也就是谷歌官方提供的方案,项目地址如下所示:https://github.com/flutte...
  • 1、一定要把基本的数据结构,经典的算法,Unix编程,程序编译链接及计算机原理等基础知识扎牢,这些会长远影响你的职业发展。 2、 推荐从C语言入门,不单是因为很多操作系统、网络协议栈开源代码由C/C++实现,更多是...
  • 2.1.1.模仿Android原生服务接口,如WifiManager,规划自己的Manager 2.1.2.为我们的Manager生成AIDL 2.1.3.编写系统级服务 2.1.4.注册服务 2.1.5.初始化服务 2.1.6.添加编译规则 2.1.7.为新服务添加SELinux...
  • 曾听过很多人说Android学习很简单,做个App就上手了,工作机会多,毕业后也比较容易找工作。这种观点可能是很多Android开发者最开始入行的原因之一。 在工作初期,工作主要是按照业务需求实现App页面的功能,按照...
  • 本来一直从事Android原生开发,基于一个项目需要用到html5开发,从而学习了html、html5、css、JavaScript等等知识。下面就个人从Android原生角度浅谈一下html5开发移动APP。 1、对应关系:  对于html5和html来说,...
  • 到了各大厂商手里,改源码、自定义系统,使得Android原生系统变得鱼龙混杂,然后到了不同层次的开发工程师手里,因为技术水平的参差不齐,即使很多手机在跑分软件性能非常高,打开应用依然存在卡顿现象。 APP进行...
  • android 10年了,已经积累了太多的技术,知识点,技巧,思路,这些前人都会了,并且正在创造新的思路出来,对于广大的底层 coder 来说,仅仅是追赶就很难了,更别提去自己创造了,但是现实时我们尝尝学习了很多开源...
  • cordova应用如果需要调用原生安卓接口,方法是使用cordova插件,cordova官方提供了主流原生功能的插件,但如果还不能满足需求,也可以自己开发cordova插件 以下介绍开发一个最简单的插件,功能是调用原生的toast...
  • Flutter原生插件-Android

    2020-11-29 19:08:47
    Flutter原生插件 一、什么是Flutter插件 1、Flutter的四种工程类型 a、Flutter Application ​ 全新的APP,标准的Flutter App工程,包含标准的Dart层与Native平台层 b、Flutter Module ​ 混编到已有的安卓/iOS...
  • > 此实例代码为 Android Studio 原生项目集成 Cordova 插件演示,而非通过 Cordova 直接编译,方便您在现有 Android Studio 项目中集成 Cordova 进行 H5 混合开发。 为了结构清晰及易维护性,项目分三个 Module ,...
  • 上文开发的插件没有调用原生界面,本文介绍开发带有activity的插件 本文很多操作与上文重复,重复部分会省略 首先打开plug1,先开发插件的原生代码 在以下命名空间创建一个activity 名称为Act1Activity ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,624
精华内容 11,449
关键字:

原生安卓开发结构