第一个完整Andorid项目总结

Andorid日志分析总结 Android日志分析摘要 Android日志系统主要分为Kernel、Radio、Event和Main四类日志: Kernel日志记录Linux内核信息 Radio日志记录通信相关日志 Main日志等同于DDMS中看到的应用日志 Event日志记录系统级事件 日志级别从低到高分为V(Verbose)、D(Debug)、I(Info)、W(Warn)、E(Error)、F(Fatal)、S(Silent)。可通过adb logcat命令配合-b参数抓取特定类型日志,如adb logcat -b radio抓 阅读详情
本文目的:把自己一阶段的东西进行总结,拿出来和大家分享,也希望从读者的评论那里得到启发。

本人水平:华东师范大学软件学院毕业,做过两个J2EE项目,一个J2ME项目,一个Android项目(基本就靠Java混饭吃)。

项目介绍:一款IM应用,类似于QQ,用户群是企业员工,和企业QQ是竞争对手。下载地址:http://apk.gfan.com/Product/App278699.html。

类似项目介绍:陌陌,QQ,微信等等,说白了就是手机即时聊天软件。个人认为,手机聊天软件中,光从用户体验来说,做的最好的是陌陌(也不妄称约炮神器,昨晚上我下载了陌陌,今天就钓到一个贵州少女)。

好了,言归正传,开始项目的点点滴滴。整个项目经历了前期需求分析,技术要难点定位,编码/测试,验收测试,上架(看了项目阶段是不是觉得有问题?他妈的确实有问题,后期吃了很多苦)。

前期需求分析:这个简单,就是在规定的项目时间内,计划完成多少功能。由于是给自己公司做产品,所以肯定要分一期,二期……,由于时间关系,我们第一期只完成最简单的单人聊天。然后根据其他已有的聊天软件,设计组给出了最初的设计稿(由于设计组人太少,只给出了最简单的原型设计,其他的,都是在PC组同事帮助下完成的功能设计)。

技术要难点定位:这里就简单的说了,从我开始做这个项目到现在,觉得有两块地方比较难。1.原始数据的拉取;2.通信协议的选择。下面展开分析。
       原始数据的拉取:做一个聊天软件,大家可能觉得功能难点在聊天模块,其实不然,软件的初始化才是难点。要聊天,你总要有你的好友,好友的状态之类的数据哇。由于我们的软件是针对企业级的,数据量非常大,好友上限是20000,那么意思就是,你还没有聊天之前,可能要拉取20000人的基本资料……在这一块,开始参考了PC版的成熟算法,但是效果非常不理想,性能很棒的手机,在WIFI状态下,拉取20000人的账户,也要几分钟,这是用户不能接收的。后来采用的并发请求的方式,比较好的解决了这个问题。这里的并发指的是:逻辑层把要请求的数据包全部发送给网络层,网络层缓存起来,再不停的发送。(这种方式为什么比发送一个包,接收以后再发送下一个包好?不清楚的可以留言,我会回复)。现阶段,拉取5000人的账户,时间大概在30秒,当然还有优化的空间。做手机应用,应该有一个共识——弱化初始化。什么意思呢?就是登陆流程应该尽量简化,只拉取必要的数据,其他数据,可以在进入功能界面,用户开始使用功能以后再拉取。在本项目中,比如用户照片,用户状态等,都可以在“非繁忙”时段拉取,这样,初始化速度会快很多,用户体验会好很多。
      通信协议的选择:针对这个问题,我写了一篇专门的博客:http://blog.youkuaiyun.com/coding_or_coded/article/details/7266536,最后我们采用了TCP协议,后来也遇到了很多问题。在移动环境下,做TCP通信,还是有一定的挑战性的:在2G,3G,WIFI切换情况下,TCP通道都会无条件断掉,更不说在网络不稳定的地段,比如商场,地铁之类的,你的TCP链接会不停的断,然后你就必须不停的重新连接服务器。在这里,TCP连接断掉是不可避免的,我们要做的工作是在断了以后,怎么快速的恢复主功能(聊天功能)。在服务器端,我们采用了TCP复用机制,简单的说就是,你TCP断了,但是你在规定的时间又连上去了,那么,认为你是合法的用户,你就不需要再次走登陆流程了,就可以直接聊天了(这里细节很多,有想深入了解的可以给我留言)。
      补充一些额外的点:
1.通信数据格式:在这种数据密集型的项目中,采用XML,json之类的格式,绝对是找死,你可以很轻松的做出来,但是在正常的网络环境下,你的通信速度,绝对会比同类产品慢一拍,因为你的数据格式决定了你的数据大小,数据大小决定了通信时长。比较通用的做法就是自己拼凑byte数组,规定每个byte要表达的意义,然后一次通信规定一条协议,这可以最大程度的减少通信的数据。
2.数据库:由于聊天软件,多用户是必然的,而针对于我们这样的大数据项目,数据库的设计也是一个难点。数据库的设计是我单独完成的,我采用的是一个用户对应一个数据库,这样数据库的查询数据可以得到一定的保证。同时,为了数据响应速度,在适当的尺度,可以考虑冗余数据来减少多表查询,这对速度有很大的帮助。最后,在大批量的插入和读取时,有三点可以帮助我们提升速度:A.使用原生sql语句,而不是android封装的API,封装,代表着优雅,但是也代表着效率低下,在小数据量的时候,我肯定采用android的API,傻逼才用原生语句。但是一旦数据量大了,你就需要掂量掂量。 B.使用sql预编译,这样可以减少sql语句编译次数,也可以较大程度的提升性能。C.使用事务,把多条sql语句放在一个事务中完成,既可以保证数据的完整性,也可以大大的提升性能。在5000条数据的插入测试中,使用上面每一点,基本上都可以提升一倍的速度。简而言之,比如你做一个大批量的插入,开始需要1分钟,但是采用了这三种方式,你最终的时间,只需要几秒钟。(需要成熟实例代码的可以留言)


编码/测试:大家也看到了,技术难点分析以后,就开始编码了,他妈逼的,连一个系统架构设计,或者编码规范制定都没有。这样的导致的结果就是,到了项目后期,由于开始没有做任何的项目规范,每个人的实现方式不同,整个代码的风格非常不一致,每个人负责的那一块,出了问题,只能由当事人修改……    而且由于开始没有良好的系统架构,整个项目模块之间耦合性非常的高,修改一个地方,极可能引起其他问题。程序员非常被动。对不起,我已经无力吐槽了,笑,懂?

测试:以前我很讨厌测试人员,总觉得他们在找麻烦,但是如果你真的想做好一个应用,一个优秀的测试是多么的重要,尊重测试人员吧,他们重复无数次无聊的操作,仅仅是为了找到你犯的错。当然,有些测试也很讨厌,特别是验收测试中(就是快上线了),一个屁大的问题,非要闹的大家都知道,整的开发人员很没有面子,其实在验收测试中,小bug是可以下期再修改的,这个大家都可以理解。

上架:在上架之前,简单说一下打包的问题,打包的时候,要自己生成一个key,那么,这个key的有效期最好是长一点(怎么的也要50年吧),而且这个key一定要保存好,你的应用,在以后的任何一次打包中,都应该使用这个key,如果你不这样做,也可以,等着老板骂娘吧。


下面谈一下项目中遇到的一些问题:

1.软件进不去:由于项目数据量比较大,在性能差一点的手机,拉取数据过程中,总是stack溢出,导致登陆失败,然后软件退出。后来发现是使用了递归方法,当然,为什么使用递归就会导致stack溢出也没有去查(有些人就是喜欢把问题解决了就算了,真正的原因不关心),直接使用了for循环替代递归。当然,从大学学习算法的时候,我就没有搞懂递归,始终觉得,可以设计递归算法的人,很厉害……

2.CPU消耗达到90%:QQ的CPU消耗基本在1%以下,而我们的应用居然不小心就达到90%,你让我情何以堪啊……   后来采用工具分析,也没有分析出什么玩意(可能是我笨),但是笨鸟先飞,老子不知道问题在哪里,那我就一段代码一段代码的注释,直到找到有问题的类,方法,代码段。后来才发现,有一个消息循环没有退出,只要运行到那里以后,就会一直给UI线程的消息队列发送消息,这样导致CPU消耗非常高。CPU消耗高了以后,机器就会发热,热到烫手,都他妈的可以煮鸡蛋了……    而且我把手机连上电脑,边充电边调试,一会儿就会报电量不足,要停一会儿,才可以继续……

3.用户界面卡死:引起原因,在多线程同步的时候,大量使用全局对象锁,导致等待,卡死。在这里给各位屌丝普及一下Java锁的种类(在d8,估计清楚这点的不超过三个),Java锁分为两种,一种是类锁(synchronized加在方法上,而且方法有static关键字),一种是对象锁(synchronized加在方法上,但是这个方法不是静态方法,或者直接是synchronized代码块)。在使用synchronized的时候,范围要尽量小,而且采用的锁对象波及的范围也要小(听不懂的可以留言,就这一点展开说都至少要写一篇文章)。

4.软件不能正常退出:可悲的是,现在都还没有找到具体原因,采用了网上说的多种方案,都他妈的退不出去,具体的bug是activity被杀掉的时候,又莫名其妙的启动了。后来的解决办法是在每个activity生成的时候,给它注册一个广播,然后要杀死所有activity的时候,只需要发送一个广播,其他的就不用管了。

5.沟通:这里讲两个小例子:一个是我同学,他大学基本上没有敲过代码,第一家公司和我一样,也觉得他敲代码的能力不强,但是领导很认可他,后来我才发现,这个人很会交流,他不懂的话,他就把问题抛出来,让大家一起解决。整个团队效率很高,但是有很多程序员不是这样……   第二个例子:我们项目组的人就特别不喜欢交流,严重到他在认真敲代码的时候,你去问他东西,他都很不乐意。当然,他有问题,也不会抛出来,都自己搞……      记得我一个类中有一个方法,我是自己用的,使用的是private关键字,结果,后来程序报错,就报在这个方法,我才发现,这个方法被别人改为public了,而且到处在调用,真的,我无力吐槽……

6.未解决问题:长时间运行于这
后台,程序被Android系统杀死。个我实在是没有找到合适的解决办法,参考了QQ的表象(从软件行为判断,具体的实现我也不清楚),在系统杀死程序的时候,通知栏图标并不会消失,QQ的实现方式估计是:在程序被杀死以后,如果有新的消息,则服务器push到手机,一旦手机接收到消息,则发出提醒(通知栏,声音,震动),用户点击通知栏时,则重新初始化程序。这样的结局就是:用户一致可以收到消息,也就是达到了一个目的:程序一直在运行的假象。如果有这方面经验的朋友请不吝赐教……

7.数据并发问题:根据应用的特点,客户端会多次发送请求包到服务器,比较好的方式是并发处理,一次性把所有包发出去,然后再慢慢的接收。但是这样会有一个问题,TCP的缓冲区可能溢出。这个时候,可以根据一个经验值来做并发控制,比如一次性发50个包,等这些包接收完了以后,才发下一批次的50个包。注意这里的并发控制应该在网络模块处理,如果放在业务模块,会有两个问题:1.业务模块不关心并发控制,并发控制会让业务模块代码凌乱;2.很多业务都需要并发控制,这可能导致并发控制代码满天飞。

8.crash问题:crash是最不能让用户接受,也最让开发人员难受的bug。在项目稳定以后,crash发生的情况不会很多,而且发生的条件不容易模拟,这给crash的修改带来了挑战,不容易复现和定位的bug,是真BUG……   解决这个问题的唯一办法就是crash报告,当发生crash时,记录下crash的堆栈信息,然后下次使用软件时上传crash信息,我们根据crash信息来跟踪和定位bug。crash的堆栈信息一定要尽量详细,这会给修复人员带来帮助。

下面是项目里面一些不错的工具类:

1. 关于SharedPreferences的封装类:
package com.imo.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

import com.imo.global.IMOApp;

/**
 * SharedPreference封装
 */
public class PreferenceManager {
	/**
	 * 在指定的文件中保存数据
	 * 
	 * @param fileName
	 *            文件名称
	 * @param objs
	 *            数组{key,value}
	 */
	public static void save(String fileName, Object[] objs) {
		try {
			SharedPreferences sp = IMOApp.getApp().getSharedPreferences(fileName,Context.MODE_APPEND);//IMOApp.getApp()代表Application
			Editor editor = sp.edit();
			if (objs[1] instanceof String) {
				editor.putString(objs[0].toString(), objs[1].toString());
			} else if (objs[1] instanceof Integer) {
				editor.putInt(objs[0].toString(),Integer.parseInt(objs[1].toString()));
			} else if (objs[1] instanceof Long) {
				editor.putLong(objs[0].toString(),Long.parseLong((objs[1].toString())));
			} else if (objs[1] instanceof Float) {
				editor.putFloat(objs[0].toString(),Float.parseFloat((objs[1].toString())));
			} else if (objs[1] instanceof Boolean) {
				editor.putBoolean(objs[0].toString(),Boolean.parseBoolean((objs[1].toString())));
			}
			editor.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 在指定的文件中读取数据
	 * 
	 * @param fileName
	 *            文件名称
	 * @param objs
	 *            数组{key,defaultValue}
	 */
	public static Object get(String fileName, Object[] objs) {
		try {
			SharedPreferences sp = IMOApp.getApp().getSharedPreferences(fileName,Context.MODE_APPEND);
			if (objs[1] instanceof String) {
				return sp.getString(objs[0].toString(), objs[1].toString());
			} else if (objs[1] instanceof Integer) {
				return sp.getInt(objs[0].toString(),Integer.parseInt(objs[1].toString()));
			} else if (objs[1] instanceof Long) {
				return sp.getLong(objs[0].toString(),Long.parseLong((objs[1].toString())));
			} else if (objs[1] instanceof Float) {
				return sp.getFloat(objs[0].toString(),Float.parseFloat((objs[1].toString())));
			} else if (objs[1] instanceof Boolean) {
				return sp.getBoolean(objs[0].toString(),Boolean.parseBoolean((objs[1].toString())));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

2.一个简单的去重算法(设计的目的:客户端不断的接收到消息,但是有可能有重复的消息,客户端要负责去重)
package com.imo.util;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * 
 * 简单去重算法
 * 
 * 定制的默认大小为capacity的容器,当容量大于capacity+count时,删除count个元素
 * 
 * @author fengxiaowei
 * 
 */
public class CustomList {
	private Map<Integer, Integer> map = new HashMap<Integer, Integer>();
	private LinkedList<Integer> link = new LinkedList<Integer>();

	private int capacity = 100;

	private int count = capacity / 2;

	public CustomList(int capacity) {
		this.capacity = capacity;
		this.count = capacity / 2;
	}

	public boolean contains(Integer obj) {
		return map.containsKey(obj);
	}

	public void add(Integer obj) {
		if (map.size() >= capacity + count)
			for (int i = 0; i < count; i++) {
				map.remove(link.removeFirst());
			}
		map.put(obj, obj);
		link.add(obj);
	}
	
	public void clear(){
		map.clear();
		link.clear();
	}
	
	@Override
	public String toString() {
		String result ="";
		for(int i=0;i<map.size();i++){
			result = result +"  "+ link.get(i);
		}
		return result;
	}

}

一个Toast的工具类,优化了Toast的显示逻辑(用户不停的点击,会不停的弹出Toast,而且Toast在屏幕上持续很久):
public class ToastUtil {
 
    private static Handler handler = new Handler(Looper.getMainLooper());
 
    private static Toast toast = null;
     
    private static Object synObj = new Object();
 
    public static void showMessage(final Context act, final String msg) {
        showMessage(act, msg, Toast.LENGTH_SHORT);
    }
 
    public static void showMessage(final Context act, final int msg) {
        showMessage(act, msg, Toast.LENGTH_SHORT);
    }
 
    public static void showMessage(final Context act, final String msg,
            final int len) {
        new Thread(new Runnable() {
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (synObj) {
                            if (toast != null) {
                                toast.cancel();
                                toast.setText(msg);
                                toast.setDuration(len);
                            } else {
                                toast = Toast.makeText(act, msg, len);
                            }
                            toast.show();
                        }
                    }
                });
            }
        }).start();
    }
 
 
    public static void showMessage(final Context act, final int msg,
            final int len) {
        new Thread(new Runnable() {
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (synObj) {
                            if (toast != null) {
                                toast.cancel();
                                toast.setText(msg);
                                toast.setDuration(len);
                            } else {
                                toast = Toast.makeText(act, msg, len);
                            }
                            toast.show();
                        }
                    }
                });
            }
        }).start();
    }
 
}



等待持续更新……

andorid下从相册选取/拍照选取一张相片并剪切 在Android编程中,从相册选取或是拍照选取一张照片然后对其进行剪切的需求非常的多 之前的一篇文章只说到如果从相册中获取一张照片,今天就跟大家说说如何将获取到的相片进行剪切 完整源码下载 我们先说一下思路,在android系统中就自带了图片剪切的应用,所以,我们只需要将我们获取到的相片传给图片剪切应用,再将剪切好的相片返回到我们自己的界面显示就ok了 第一步,我们可以先激活系统图片或 阅读详情

相关推荐

近百个Android优秀开源项目总结

安卓巴士总结了近百个Android优秀开源项目,覆盖Android开发的每个领域

安卓项目经验总结

安卓项目经验总结 我觉得安卓把第一行代码看了之后,做项目是提升技术最快的方法了。可能最开始不会写,那就在网上找模板,先把别人的读懂了,再添加到自己的代码中。用别人的代码会出现各种各样的bug,我最开写代码时就是把别人某一部分代码复制过来,然后发现可以运行但总是在打开的时候报错,出现NullPointerException异常。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(...

GZAY的博客 1276

电磁阀的符号解读

先数方框数量定“几位”(工作位置数 );数接口数量(P、A、R等 )定“几通”;看箭头、截断符号,结合常态位(弹簧侧/中间位 ),分析通电/断电时的通路切换;字母(P、A、R )、线圈(单/双电控 )、弹簧(复位 )辅助确认功能(如NO/NC对应常态通断 )。不同厂家符号细节(如编码、线圈画法 )有差异,遇到陌生符号,建议结合产品手册、品牌规范核对,就能精准读懂电磁阀的“语言”啦~

创新改变世界! 6890

Android项目总结

项目总结 最近在公司做了一个非常轻量级别的app,不过里面还是有一些知识点,是查了资料之后才会的,现在app基本做完了,整体总结一下。 1.获取当前app的一些基础信息: public static final boolean DEBUG = BuildConfig.DEBUG; //以下是能获取到的信息 public static final boolean DEBUG = Boolean.p...

qq_35711549的博客 1259

电信光猫隐藏的VOIP功能揭秘:不用座机也能打电话(EasySip实战)

本文揭秘了电信光猫隐藏的VOIP功能,通过EasySip实战演示如何无需座机实现高清通话。详细解析了光猫的SIP协议支持、语音VLAN配置及网络架构优化,帮助用户利用现有设备提升通话质量并扩展设备兼容性,特别适合智能家居和企业级应用场景。

weixin_29268385的博客 755

安卓模拟器绕过检测全解析:雷电、MuMu、蓝叠、逍遥、夜神与WSA完整指南

随着手机游戏和应用的普及,越来越多的用户选择在PC上通过模拟器来运行安卓应用。然而,许多应用和游戏为了防止作弊或出于安全考虑,会检测是否运行在模拟器环境中。本文将详细介绍各大主流模拟器的检测绕过方法,帮助用户在电脑上流畅体验各类安卓应用。1. 获取模拟器系统镜像2. 使用ROM厨房工具修改系统文件3. 替换模拟器的系统镜像雷电模拟器:适合游戏,推荐使用MAGISK + EdXposed方案MuMu模拟器:适合中度游戏,推荐太极框架蓝叠模拟器:适合国际应用,推荐MAGISK方案逍遥模拟器。

专注技术分享 3万+

Android项目开发总结

在做过了N个公司项目开发的时候,我常常在怀疑人生,为什么大部分时间都浪费在搬砖的事情上,每开始一个新项目这个念头更是涌上心头,终于在经历了那么多项目开发后,我做出了一件常人都不太愿意去做的事:搭架构和做模板 经过对每个做过的项目进行分析,把其中的共同点抽取并且分离开来,历时一个多月,经过不断地修改,不断地修改,不断地修改...... 在今天,正式开源了,这个项目几乎适用于任何新项目的开发,可以...

haoxuhong的博客 3383

单细胞转录组聚类分析R包——SC3的应用

前言 在做单细胞相关聚类分析的过程中,为了研究异质性,发现了一种专门用于单细胞转录组的聚类分析R包——SC3(single cell consensus clustering,单细胞一致性聚类)。该聚类算法发表于Nature Methods(2017),能够让单细胞RNA-seq基于转录组特征对细胞类型进行定量表征。这是一种用户友好的无监督聚类工具,它通过一致方法将多个聚类解决方案组合在一起,从而得到高精度和鲁棒性的分群结果。SC3包的官方具体使用教程见:http://www.bioconductor.or

m0_51042606的博客 5005

Android开发——项目最终总结

1.项目优点3.Android应用发布的探索如果你最终看到了这篇文章,我想你表达一波歉意,由于整个Android项目属于敏捷开发,因此很多知识点我没能解释那么透彻,更多的是介绍有什么工具怎么使用它。由于自己基础不好,还是个考研族,整个开发也就花了7天左右0基础上手Android,确实是时间不够,哈哈哈,真心希望能得到理解。

weixin_46560512的博客 2174

Keysight ADS新手必看:3分钟搞定TDR模拟的保姆级教程(附差分信号设置技巧)

本文为Keysight ADS新手提供TDR模拟的保姆级教程,详细介绍了从基础环境准备到差分信号设置的全流程。通过内置模板调用、待测器件连接和仿真结果解读,帮助用户快速掌握TDR模拟技术,特别包含差分信号配置技巧,提升信号完整性分析效率。

weixin_30872157的博客 195

手把手教你做基于stm32的红外、语音、按键智能灯光控制(上)

这次项目使用的板子是stm32f103c8t6最小系统板,这个板子在tb上都能够买到,随便一个最小系统板都可以,== 注意在买最小系统板的时候需要买一个stlink下载器来下载程序。显示模块是使用的0.96英寸的OLED屏幕,注意是使用的IIC通信协议的OLED屏幕,不是使用SPI总线协议的。这次写的代码还顺便集成了检测温湿度的功能,所以要使用DHT11温湿度传感器,来采集温度。本文所设计的基于单片机的灯光控制系统主要由模式选择功能、手动模式和自动模式组成。LED灯自然就是要控制的部件了。

nbbskk的博客 6557

Andriod项目总结

项目总结 一、Game2048 1)开发流程: 1.使用LinearLayout作为界面主布局(搭建不同显示区域); 2.编写游戏主类GameView(继承至GridLayout并实现相应构造方法),并通过修改xml文件中的标签实现绑定; <!-- 游戏界面布局--> <com.mertrix.game2048.GameView android:id="@+id/gameView" android:layout_width="match_parent" an

Mertrix-ITCH 470

SBP依赖计算中的蝴蝶效应:一个Prefab修改如何触发全量重建?

本文深入探讨了Unity中SBP(Scriptable Build Pipeline)依赖计算的蝴蝶效应,解析了Prefab修改如何触发全量重建的机制。通过分析Asset与Object的层级关系、依赖计算的三种维度及CacheEntry系统,揭示了全量重建的根本原因,并提供了依赖可视化工具开发、优化策略与最佳实践,帮助开发者提升构建效率。

weixin_29015051的博客 444

andorid平板中安装完整的ubuntu系统

1,准备 硬件:平板,我用的是三星gt-n5120 前提:android要root     安装busybox(安装器好像自带),我的是早前安装好的 软件:1)安装器:http://linuxonandroid.org/     2)脚本和系统镜像:http://sourceforge.net/projects/linuxonandroid/files/ 教程:1)http://www

roy9494的专栏 1万+

基于 YOLOv26 的光伏板热斑检测系统:红外+可见光

本文提出了一种基于YOLOv26的光伏板热斑检测系统,采用红外+可见光双模态融合方案。系统架构包含数据预处理、热斑检测、故障诊断和维修决策等模块,结合无人机巡检与地面监控。关键技术包括YOLOv26目标检测模型、双模态数据融合、边缘计算部署等。研究构建了包含多种故障类型的光伏板专业数据集,并采用数据增强技术提升模型性能。系统实现了热斑检测、分类(轻微/中等/严重/危急)以及功率损失评估等功能,为光伏电站智能运维提供解决方案。

一键难忘的博客 497

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

andorid_relativelayout

andorid相对布局(RelativeLayout) 界面伸缩性很强,具有很大的灵活性,可以设置父类,属性较多,也相对较复杂。 重要属性(该部分不属于原创:http://blog.sina.com.cn/s/blog_40797b1001010vwt.html): 第一类:属性值为true或false android:layout_centerHrizontal 水平居中 andr...

QIN_POPEYE的博客 100

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Andorid项目源码(167套)

Andorid项目源码(167套)

weixin_43860634的博客 240

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

andorid开发环境搭建

本系列适合0基础的人员,因为我就是从0开始的,此系列记录我步入Android开发的一些经验分享,望与君共勉!作为Android队伍中的一个新人的我,如果有什么不对的地方,还望不吝赐教。 在开始Android开发之旅启动之前,首先要搭建环境,然后创建一个简单的HelloWorld。本文的主题如下: 1、环境搭建 1.1、JDK安装 1.2、Eclipse安装 1.3、An...

a495673765的博客 133

Andorid项目构建问题处理和官方库升级参考

由于各种库和插件经常升级,更新这些库和插件时,项目构建经常会出现构建失败的问题,这些问题出现的原因大概率是库和插件与gradle插件版本不对应,gradle插件和gradle版本不一致,库和google api版本不一致,这些库和Android studio的版本不配套等等,总的来说就是版本对应出了问题。把这些版本调整成配套的,基本就解决问题了。 版本文档汇总(蓝色标题为链接,可点击跳转到官方文档) The Google Services Gradle Plugin 通过项目的build文件添加classp

学习飞翔 595

android 酷欧天气完整项目

先要建议三张表:province、city、county,分别用于存放省市县的数据信息。 Province.java package com.example.lenovo.coolweather.db; import org.litepal.crud.DataSupport; /** * 代表省的数据库表 */ public class Province extends DataSu

一个北漂的程序猿 3040

android平板刷ubuntu6,andorid平板中安装完整的ubuntu系统

1,准备硬件:平板,我用的是三星gt-n5120前提:android要root安装busybox(安装器好像自带),我的是早前安装好的软件:1)安装器:http://linuxonandroid.org/2)脚本和系统镜像:http://sourceforge.net/projects/linuxonandroid/files/教程:1)http://www.ithome.com/html/and...

weixin_33092503的博客 1855

Andorid实现TCP通讯

Android实现TCP通信的两种模式:客户端模式(点对点)和服务端模式(广播)。客户端通过指定IP和端口连接服务端,服务端监听端口等待客户端接入。界面包含模式切换开关、连接状态显示、消息输入框和滚动消息区。关键步骤包括:创建Socket/ServerSocket对象、获取输入输出流、读写数据及关闭连接。代码提供了TCP通信的基本实现框架,支持双向消息传输和连接状态管理。

Hello world! 970

完整的项目

1.这是一歀仿网易音乐的App 2.AiYaGirl爱吖妹纸送你们    3.不要错过七个完整的项目    4.菜鸟窝的 商场项目  5.开源中国   6.自定义控件    7.韦驮天视频 APP 客户端    8.基于极光推送的手机聊天系统 9.心情记事本 App 10.Andorid 小游戏—盒子与点  ...

weixin_34377919的博客 109

MVP andorid 使用

MVP整理: 参考:https://www.jianshu.com/p/57e5f75e9408 简介: 首先说一下大家都熟悉的mvc,mvc由三部分组成,分别是M-Model-模型、V-View-视图、C-Controller-控制器,随着功能以及业务逻辑的增加,我们希望业务逻辑model和展示层view之间的结构和关系能够更清晰,所以增加了controller,来实现两者之间的部分控制和...

Silence_Sep的博客 207

Andorid 反编译App,2024年最新Android实战项目视频

我这里整理了一份完整的学习思维以及Android开发知识大全PDF。当然实践出真知,即使有了学习线路也要注重实践,学习过的内容只有结合实操才算是真正的掌握。一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**[外链图片转存中…(img-vI91ZJ9w-1712682705279)]

2201_75604580的博客 437
上一篇: 简单工厂模式
下一篇: 写更少的代码
coding_or_coded
博客等级 码龄16年 216粉丝 115原创
评论 21
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值