Android 垃圾分类APP(七)历史记录

简介: Android 垃圾分类APP(七)历史记录

历史记录


前言


 本文将是这个垃圾分类APP的暂定最后一篇,后面可能有,可能没有,就像薛定谔的猫一样。


正文


 本文讲述垃圾分类的历史记录,为什么要这个记录呢?因为可能有时候我查询过某一件物品的分类,然后我不记得了,再查询一次我觉得麻烦,我就希望能看到以往的查询记录。这是一个很合理的要求,不是吗?


一、建表


要保存历史数据,首先要有一个表,在上一篇文章中,我们已经建过一个News了,下面再建一个History表,在model包下新建一个History类,里面的代码如下:


package com.llw.goodtrash.model;
import org.litepal.crud.LitePalSupport;
/**
 * 历史记录实体
 *
 * @author llw
 */
public class History extends LitePalSupport {
    private int id;
    private String name;
    private int type;
    private int aipre;
    private String explain;
    private String contain;
    private String tip;
    private String dateTime;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public int getAipre() {
        return aipre;
    }
    public void setAipre(int aipre) {
        this.aipre = aipre;
    }
    public String getExplain() {
        return explain;
    }
    public void setExplain(String explain) {
        this.explain = explain;
    }
    public String getContain() {
        return contain;
    }
    public void setContain(String contain) {
        this.contain = contain;
    }
    public String getTip() {
        return tip;
    }
    public void setTip(String tip) {
        this.tip = tip;
    }
    public String getDateTime() {
        return dateTime;
    }
    public void setDateTime(String dateTime) {
        this.dateTime = dateTime;
    }
}


然后在litepal.xml中配置一下。


20210422090200949.png


注意一下,当你的数据库已经创建之后,如果要使新增的表生效,则需要数据库的版本进行升级,比如之前是1,现在我新增了一个表,那么改成2,这样拟新增的表才会生效。或者你不升级,还是1,你只要把原来的APP卸载重装就可以。


二、新增历史记录页面


在ui包下新建一个HistoryActivity,布局是activity_history.xml。下面对于这个也页面的布局还是要想一下该怎么做,首先肯定要有一个列表用来展示这个数据吧。其次要是没有数据的时候显示一片空白好像也不合适。所以还需要一个显示空数据的布局。


好的,目前先搞定这两步。先写空数据布局,在layout下新建一个layout_empty_data.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:gravity="center"
    android:orientation="vertical">
    <ImageView
        android:src="@mipmap/icon_empty_data"
        android:layout_width="@dimen/dp_100"
        android:layout_height="@dimen/dp_100" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/dp_12"
        android:text="空空如也"
        android:textSize="@dimen/sp_16" />
</LinearLayout>


这里用到的icon_empty_data图标如下:


20210422092411782.png


下面来写这个activity_history.xml代码:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    tools:context=".ui.HistoryActivity">
    <androidx.appcompat.widget.Toolbar
      android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/white"
        app:navigationIcon="@mipmap/icon_back">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="历史记录"
            android:textColor="@color/black"
            android:textSize="@dimen/sp_18" />
    </androidx.appcompat.widget.Toolbar>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="@dimen/dp_2">
        <include
            android:id="@+id/lay_empty_data"
            layout="@layout/layout_empty_data"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <!--历史记录列表-->
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_history"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </RelativeLayout>
</LinearLayout>


布局写好了,但是还有列表的item需要写布局和适配器。


三、列表适配器


首先写item的布局,在layout下新建item_history_rv.xml,里面的代码如下:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/dp_1"
    android:background="@color/white"
    android:orientation="vertical"
    android:padding="@dimen/dp_12">
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="物品名称"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_16" />
    <TextView
        android:id="@+id/tv_datetime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:text="保存时间"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_14" />
    <TextView
        android:id="@+id/tv_type"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_name"
        android:layout_marginTop="@dimen/dp_8"
        android:text="垃圾类型"
        android:textColor="@color/hint_color"
        android:textSize="@dimen/sp_14" />
    <TextView
        android:id="@+id/tv_explain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_type"
        android:layout_marginTop="@dimen/dp_8"
        android:text="解释"
        android:textColor="@color/hint_color"
        android:textSize="@dimen/sp_14" />
</RelativeLayout>


然后就是写适配器了,在adapter包下新建一个HistoryAdapter类,里面的代码如下:


package com.llw.goodtrash.adapter;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodtrash.R;
import com.llw.goodtrash.model.History;
import java.util.List;
/**
 * 历史记录列表适配器
 * @author llw
 */
public class HistoryAdapter extends BaseQuickAdapter<History, BaseViewHolder> {
    public HistoryAdapter(int layoutResId, @Nullable List<History> data) {
        super(layoutResId, data);
    }
    @Override
    protected void convert(BaseViewHolder helper, History item) {
        helper.setText(R.id.tv_name, item.getName())
                .setText(R.id.tv_datetime,item.getDateTime())
                .setText(R.id.tv_explain, item.getExplain());
        TextView tvType = helper.getView(R.id.tv_type);
        switch (item.getType()) {
            case 0:
                tvType.setText("可回收垃圾");
                break;
            case 1:
                tvType.setText("有害垃圾");
                break;
            case 2:
                tvType.setText("厨余垃圾");
                break;
            case 3:
                //干垃圾即其他垃圾
                tvType.setText("干垃圾");
                break;
            default:
                tvType.setText("可回收垃圾");
                break;
        }
    }
}


四、历史记录页面初始化


修改HistoryActivity页面代码如下:


package com.llw.goodtrash.ui;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import com.llw.goodtrash.R;
import com.llw.goodtrash.adapter.HistoryAdapter;
import com.llw.goodtrash.model.History;
import com.llw.mvplibrary.base.BaseActivity;
import org.litepal.LitePal;
import java.util.List;
/**
 * 历史记录
 * @author llw
 */
public class HistoryActivity extends BaseActivity {
    //工具栏
    private Toolbar toolbar;
    //空数据布局
    private LinearLayout layEmptyData;
    //历史列表
    private RecyclerView rvHistory;
    //适配器
    private HistoryAdapter mAdapter;
    //历史数据列表
    private List<History> mList;
    @Override
    public void initData(Bundle savedInstanceState) {
        initView();
    }
    /**
     * 页面初始化
     */
    private void initView() {
        toolbar = findViewById(R.id.toolbar);
        //设置页面状态栏
        setStatubar(this, R.color.white, true);
        back(toolbar,false);
        layEmptyData = findViewById(R.id.lay_empty_data);
        rvHistory = findViewById(R.id.rv_history);
        //获取数据库中的历史数据
        mList = LitePal.findAll(History.class);
        if (mList.size() > 0) {
            //设置列表的数据
            mAdapter = new HistoryAdapter(R.layout.item_history_rv, mList);
            rvHistory.setLayoutManager(new LinearLayoutManager(context));
            rvHistory.setAdapter(mAdapter);
            layEmptyData.setVisibility(View.GONE);
            rvHistory.setVisibility(View.VISIBLE);
        } else {
            //隐藏列表
            layEmptyData.setVisibility(View.VISIBLE);
            rvHistory.setVisibility(View.GONE);
        }
    }
    @Override
    public int getLayoutId() {
        return R.layout.activity_history;
    }
}


下面我们增加一个进入历史记录页面的入口。


修改activity_main.xml。在NestedScrollView下面加上一个浮动按钮:


  <!--浮动按钮 历史记录-->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/btn_history"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/dp_20"
        android:src="@mipmap/icon_history"
        android:onClick="jumpHistory"
        app:backgroundTint="@color/white"
        app:backgroundTintMode="screen"
        app:fabSize="mini"
        app:hoveredFocusedTranslationZ="@dimen/dp_18"
        app:pressedTranslationZ="@dimen/dp_18" />


位置如下图所示:


20210422092627671.png


icon_history图标


20210422092654715.png


然后在MainActivity中写一个jumpHistory方法,代码如下:


  /**
     * 进入历史记录页面
     */
    public void jumpHistory(View view) {
        gotoActivity(HistoryActivity.class);
    }


运行一下;


20210422093015776.gif


嗯,现在是空空如也,下面来添加记录,进行垃圾分类结果返回的第三有三个,分别是文字输入进行垃圾分类,语音输入进行垃圾分类,还有图像输入进行垃圾分类。下面先来看看怎么保存这个垃圾分类的信息。


五、保存历史记录


在前面的文章中当进行分类时,会关联出很多物品,而我们要保存和我输入物品的一致性才行,比如当我搜索水杯时,会出现的结果有:水杯、保温杯、汽车杯等一些物品。而我只需要保存水杯的结果到历史记录就可以了。那么在写保存方法时首先要比对这个搜索结果。一致才保存。


下面来写代码,这里我还是写一个帮助类。在utils下新建一个HistoryHelper类,里面的代码如下:


package com.llw.goodtrash.utils;
import android.util.Log;
import com.google.gson.Gson;
import com.llw.goodtrash.model.History;
import com.llw.goodtrash.model.TrashResponse;
import com.llw.mvplibrary.network.utils.DateUtil;
import org.litepal.LitePal;
import java.util.List;
/**
 * 历史记录帮助类
 *
 * @author llw
 */
public class HistoryHelper {
    public static final String TAG = "HistoryHelper";
    /**
     * 查询所有历史记录
     *
     * @return 结果列表
     */
    public static List<History> queryAllHistory() {
        return LitePal.findAll(History.class);
    }
   /**
     * 是否存在历史记录
     *
     * @param name 物品名
     * @return true or false
     */
    public static boolean isHaveHistory(String name) {
        List<History> histories = LitePal.where("name = ?", name).find(History.class);
        return histories.size() > 0;
    }
    /**
     * 保存历史记录
     *
     * @param list 需要保存的数据
     * @param word 物品名称
     */
    public static void saveHistory(List<TrashResponse.NewslistBean> list, String word) {
        for (TrashResponse.NewslistBean bean : list) {
            //遍历返回数据,找出返回结果中与搜索内容一致的数据,保存到数据表中
            if (bean.getName().equals(word)) {
                //保存数据前先查询是否存在数据
                List<History> historyList = queryAllHistory();
                //有数据则遍历检查保存
                if (historyList.size() > 0) {
                    if (!isHaveHistory(bean.getName())) {
                        //不存在则直接保存
                        saveHistory(bean);
                    } else {
                        Log.d(TAG, "记录已存在");
                    }
                } else {
                    //没有数据则直接保存
                    saveHistory(bean);
                }
            } else {
                Log.d(TAG, "没有匹配到相关结果,无法保存");
            }
        }
        Log.d(TAG,new Gson().toJson(queryAllHistory()));
    }
    /**
     * 保存历史
     * @param bean
     */
    private static void saveHistory(TrashResponse.NewslistBean bean) {
        History historyBean = new History();
        historyBean.setName(bean.getName());
        historyBean.setType(bean.getType());
        historyBean.setAipre(bean.getAipre());
        historyBean.setExplain(bean.getExplain());
        historyBean.setContain(bean.getContain());
        historyBean.setTip(bean.getTip());
        //添加历史记录的保存时间
        historyBean.setDateTime(DateUtil.getDateTime());
        historyBean.save();
        if (historyBean.save()) {
            Log.d(TAG, "保存历史记录成功");
        } else {
            Log.d(TAG, "保存历史记录失败");
        }
    }
}


下面去使用一下这个方法。


首先是文字输入页面TextInputActivity。


将之前的word变成成员变量:


private String word;//输入的物品


当点击软键盘的搜索按钮时会将输入框的内容赋值给word。

20210422093951595.png


然后只要在getSearchResponse方法中保存就好了。


20210422094026683.png


下面进入声音输入页面VoiceInputActivity。


private String word;//输入的物品


进行赋值


20210422094348410.png


保存结果。


20210422094414468.png


然后是图像输入页面ImageInputActivity。


private String word;//输入的物品


然后赋值:


20210422094700295.png


最后保存。


20210422094802482.png


下面基本上都有了保存,运行一下:


20210422103742740.gif


嗯,效果还是不错的吧。


既然有保存,那就应该有删除,理论上来说,删除也是有学问的,单项删除、多选删除、全删。而删除的方法也是多种多样的,比如点击弹窗删除,侧滑删除,编辑列表删除。各种各样的,这里我就弄一个滑动删除和全选删除吧。


六、删除历史记录


先来看看侧滑删除,这里需要用到一个第三方依赖库,打开mvplibrary下的build.gradle。

在dependencies{}闭包下添加如下依赖:


//列表item侧滑删除
    api 'com.github.mcxtzhang:SwipeDelMenuLayout:V1.3.0'


添加位置如下:


20210422104858711.png


下面修改历史列表的item布局。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/dp_1"
    android:background="@color/white">
    <!--支持侧滑的布局-->
    <com.mcxtzhang.swipemenulib.SwipeMenuLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:paddingBottom="1dp">
        <!--显示文本-->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="@dimen/dp_12">
            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="物品名称"
                android:textColor="@color/black"
                android:textSize="@dimen/sp_16" />
            <TextView
                android:id="@+id/tv_datetime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:text="保存时间"
                android:textColor="@color/black"
                android:textSize="@dimen/sp_14" />
            <TextView
                android:id="@+id/tv_type"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/tv_name"
                android:layout_marginTop="@dimen/dp_8"
                android:text="垃圾类型"
                android:textColor="@color/hint_color"
                android:textSize="@dimen/sp_14" />
            <TextView
                android:id="@+id/tv_explain"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/tv_type"
                android:layout_marginTop="@dimen/dp_8"
                android:text="解释"
                android:textColor="@color/hint_color"
                android:textSize="@dimen/sp_14" />
        </RelativeLayout>
        <!-- 侧滑菜单的内容  删除 -->
        <Button
            android:id="@+id/btn_delete"
            android:layout_width="@dimen/dp_100"
            android:layout_height="match_parent"
            android:background="@color/red"
            android:text="删除"
            android:textColor="@color/white" />
    </com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</RelativeLayout>


这里有一个red的颜色,在app模块的colors.xml中添加


<color name="red">#FF0000</color>


然后修改适配器HistoryAdapter,添加侧滑菜单的点击事件。


20210422105934218.png


然后回到HistoryActivity页面去设置适配器的点击事件。


//列表item点击事件
            mAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            });


添加位置如下图所示:

20210422110140748.png


由于现在只给适配器中的一个控件设置了点击事件,因此可以直接写代码,而不需要去判断控件id了。


那么下面在HistoryHelper中添加如下两个删除方法:


  /**
     * 根据id删除数据
     * @param id id 
     */
    public static void deleteHistoryById(long id){
        LitePal.delete(History.class,id);
    }
    /**
     * 根据所有历史记录
     */
    public static void deleteAllHistory() {
        LitePal.deleteAll(History.class);
    }


下面我要修改一下HistoryActivity页面的代码:


package com.llw.goodtrash.ui;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.llw.goodtrash.R;
import com.llw.goodtrash.adapter.HistoryAdapter;
import com.llw.goodtrash.model.History;
import com.llw.goodtrash.utils.HistoryHelper;
import com.llw.mvplibrary.base.BaseActivity;
import org.litepal.LitePal;
import java.util.ArrayList;
import java.util.List;
/**
 * 历史记录
 *
 * @author llw
 */
public class HistoryActivity extends BaseActivity {
    //工具栏
    private Toolbar toolbar;
    //空数据布局
    private LinearLayout layEmptyData;
    //历史列表
    private RecyclerView rvHistory;
    //适配器
    private HistoryAdapter mAdapter;
    //历史数据列表
    private List<History> mList = new ArrayList<>();
    @Override
    public void initData(Bundle savedInstanceState) {
        initView();
        showListData();
    }
    /**
     * 页面初始化
     */
    private void initView() {
        toolbar = findViewById(R.id.toolbar);
        //设置页面状态栏
        setStatubar(this, R.color.white, true);
        back(toolbar, false);
        layEmptyData = findViewById(R.id.lay_empty_data);
        rvHistory = findViewById(R.id.rv_history);
        mAdapter = new HistoryAdapter(R.layout.item_history_rv, mList);
        rvHistory.setLayoutManager(new LinearLayoutManager(context));
        rvHistory.setAdapter(mAdapter);
        //列表item点击事件
        mAdapter.setOnItemChildClickListener((adapter, view, position) -> {
        });
    }
    /**
     * 显示列表
     */
    private void showListData() {
        List<History> historyList = HistoryHelper.queryAllHistory();
        if (historyList.size() > 0) {
            //设置列表的数据
            mList.clear();
            mList.addAll(historyList);
            mAdapter.notifyDataSetChanged();
            layEmptyData.setVisibility(View.GONE);
            rvHistory.setVisibility(View.VISIBLE);
        } else {
            //隐藏列表
            layEmptyData.setVisibility(View.VISIBLE);
            rvHistory.setVisibility(View.GONE);
        }
    }
    @Override
    public int getLayoutId() {
        return R.layout.activity_history;
    }
}     


这样改写是为了方便后面的删除操作。


20210422113716328.png


下面运行一下:


20210422113958874.gif


下面来看看全部删除,这里我们就写的简单一些,打开activity_history.xml,在toolbar控件中,增加一个全删,如下所示:


    <TextView
            android:id="@+id/tv_all_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:onClick="deleteAll"
            android:textColor="@color/black"
            android:textSize="@dimen/sp_16"
            android:layout_marginEnd="@dimen/dp_4"
            android:text="全删"
            android:padding="@dimen/dp_12"/>

20210422141441819.png


回到HistoryActivity中。


//全删
    private TextView tvAllDelete;


绑定控件id。

20210422141715920.png


控制是否显示这个按钮。


20210422141855315.png


点击全删的实现代码。


  /**
     * 全删
     * @param view
     */
    public void deleteAll(View view) {
        HistoryHelper.deleteAllHistory();
        showListData();
    }


下面运行一下:


20210422142256174.gif


那么这个APP的第一版功能就差不多了,虽然很简单吧,但也是需要花点时间去做的。

再给App弄一个桌面图标吧。


20210422142723131.png


如下图修改即可。

2021042214282629.png


相关文章
|
1月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
148 0
安卓项目:app注册/登录界面设计
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
131 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
2月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
176 2
|
2月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
105 3
|
2月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
73 10
|
1月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
240 0
|
2月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
3月前
|
API Android开发
Android P 性能优化:创建APP进程白名单,杀死白名单之外的进程
本文介绍了在Android P系统中通过创建应用进程白名单并杀死白名单之外的进程来优化性能的方法,包括设置权限、获取运行中的APP列表、配置白名单以及在应用启动时杀死非白名单进程的代码实现。
64 1
|
3月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
154 0
|
3月前
|
存储 XML Linux
深入理解操作系统:进程管理与调度策略探索安卓应用开发:从零开始构建你的第一个App
【8月更文挑战第28天】在数字世界里航行,操作系统是掌控一切的舵手。本文将带你领略操作系统的精妙设计,特别是进程管理和调度策略这两大核心领域。我们将从基础概念出发,逐步深入到复杂的实现机制,最后通过实际代码示例,揭示操作系统如何高效协调资源,确保多任务顺畅运行的秘密。准备好了吗?让我们启航,探索那些隐藏在日常电脑使用背后的奥秘。 【8月更文挑战第28天】在这个数字时代,拥有一款自己的移动应用程序不仅是技术的展示,也是实现创意和解决问题的一种方式。本文将引导初学者了解安卓开发的基础知识,通过一个简单的待办事项列表App项目,逐步介绍如何利用安卓开发工具和语言来创建、测试并发布一个基本的安卓应用
下一篇
无影云桌面