Android技术分享
1. 免费在线工具
2. 免费第三方服务
1. 免费在线工具
1.1 在线演示
1. 方便、简单
2. 默认支持部分代码高亮
public static void main(String[] args) {
System.out.println("Hello World");
Log.e("TAG", "日志猫");
int i = 110;
int j = 9;
System.out.println(i + j);
Intent intent = new Intent(this, NewActivity.class);
startActivity(intent);
}
1.2 开源中国在线工具
1. 丰富
2. 开源
1.3 json校验格式化
1. 功能强大
2. 丰富
1.4 布局id自动解析
偷懒专用
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/txv_game_gift_tag" >
<TextView
android:id="@+id/txv_game_gift_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:layout_marginBottom="4dp"
android:gravity="left"
android:singleLine="true"
android:textColor="@color/master_gray_medium"
android:textIsSelectable="false"
android:textSize="14sp" />
<TextView
android:id="@+id/txv_game_gift_remain_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/txv_game_gift_name"
android:text="@string/master_label_remain"
android:textColor="@color/master_gray_medium"
android:textSize="12sp" />
<TextView
android:id="@+id/txv_game_gift_remain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_below="@id/txv_game_gift_name"
android:layout_toRightOf="@id/txv_game_gift_remain_label"
android:layout_marginLeft="4dp"
android:textColor="@color/master_gray_dark"
android:textIsSelectable="false"
android:textSize="10sp"
android:background="@drawable/master_bg_orange_dot" />
<TextView
android:id="@+id/txv_game_gift_end_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_below="@id/txv_game_gift_name"
android:layout_toRightOf="@id/txv_game_gift_remain"
android:textColor="@color/master_gray_medium"
android:textIsSelectable="false"
android:textSize="12sp" />
</RelativeLayout>
1.5 drawable文件生成工具
偷懒专用
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="14dp" />
<gradient
android:angle="45"
android:centerColor="#7995A8"
android:centerX="35%"
android:endColor="#000000"
android:startColor="#E8E8E8"
android:type="linear" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp" />
<size
android:width="270dp"
android:height="60dp" />
<stroke
android:width="3dp"
android:color="#878787" />
</shape>
1.6 dp值换算工具

1.7 Android资源生成工具

1.8 Android Weekly订阅
1. 邮件订阅即可,每周推送
2. 包含最新技术资讯、设计资源、开源项目及开发工具
1.9 在线测试
云测
2. 免费第三方服务
2.1 推送
极光推送
http://www.jpush.cn/
信鸽推送
http://xg.qq.com/
2.2 分享服务
ShareSdk
http://sharesdk.cn/
2.3 图片处理
Aviary
http://www.aviary.com/
Camera360
需要申请合作,目前已暂停开放
2.4 视频处理
Vitamio
http://www.vitamio.org/
2.5 数据统计服务
友盟
http://www.umeng.com/
2.6 表情服务
表情大全
http://www.stickersdk.com/
2.7 App发布服务
酷传
http://www.coolchuan.com/
2.8 apk解析工具
解析资源文件
https://code.google.com/p/android-apktool/
解析代码文件
https://code.google.com/p/dex2jar/
2.9 sqlite数据库编辑工具
sqlitebrowser
http://sourceforge.net/projects/sqlitebrowser/
sqliteman
http://sourceforge.net/projects/sqliteman/?source=navbar
最大的优势只是免费
最后
几句话,装个13
站在巨人的肩膀上
代码,尽可能交给工具去完成
人不是机器,我们应该去做更重要的事情
不要重复造轮子
灵活
用他人的东西自然多少会受限于他人
所以在决定使用它的时候,本身的基础框架就要足够灵活
什么时候看哪个工具、框架不爽了,随时可以T掉它
One More Thing...
尼玛,技术分享没有代码,坑爹么!
Android Java-Bean 生成工具
Ruby语言编写
1. 基于Builder模式
2. 支持Parcelable序列化
3. 支持Gson
4. 开源 gist.github.com
## 使命行参数格式:
## ARGV[0] ==> config文件路径[必须有]
## ARGV[1] ==> 保存文件路径[必须有]
## ARGV[2] ==> 包名[必须有]
##
## 示例:
## ruby ./AndroidBeanGen.rb ./config.txt ./resp com.a.b
##
##
##
##
##
## config文件格式:
## Cls:类名1:类注释1
## 属性名1:属性类型1
## Cls:类名2:类注释2
## 属性名2:属性类型2
##
## 示例:
## Cls:ArticleReqEntity:文章请求实体
## id:int
## Cls:ArticleRespEntity:文章响应实体
## id:int
## title:String
## list:List<FooEntity>
##
##
##
## ps. 目前已知最低兼容ruby1.8.7
##
## 1.0.1(2014.03.24):增加set方法集
## 1.0.0(2014.03.20):第一版
##
##
##
# 一个类包含:类名,属性列表和内部类指针
class Clazz
def initialize(cls_name)
@cls_name = cls_name
@cls_comment = ""
@attrs=[]
@lead_cls_names=nil #前面有几个前导类名
@cls_import_advanced = 0 #是否需要导入额外内容
end
def cls_name
@cls_name
end
attr_accessor :cls_comment, :attrs, :lead_cls_names, :cls_import_advanced
end
#属性
class Attr
def initialize(type=nil,name=nil)
@type,@name=type,name
end
attr_accessor :type, :name
end
class Env
def initialize()
@clz_list = [] #类的容器
@cur_clz = nil #当前类
@cur_clz_comment = nil #当前类注释
@attr = nil #当前属性
@attr_index=0 #当前类的第几个属性
@clz_index=0 #当前属于第几个类
end
attr_accessor :clz_list,:cur_clz,:cur_clz_comment,:attr,:attr_index,:clz_index
end
$env = Env.new
# 转换首字母大写,此处算法为了兼容ruby1.8.7
def getFirstUpcase(str)
str_first_cap = str[0].capitalize
str_remainder = str[1..str.size-1]
str = "#{str_first_cap}#{str_remainder}"
return str
end
# 转换首字母小写,此处算法为了兼容ruby1.8.7
def getFirstDowncase(str)
str_first_min = "0#{str}".capitalize[1]
str_remainder = str[1..str.size-1]
str = "#{str_first_min}#{str_remainder}"
return str
end
def print_clz_list #测试容器数据
$env.clz_list.each do |clzz|
lead_cls_names = clzz.lead_cls_names
print "============"
lead_cls_names.each do |lead_names|
print lead_names + "-"
end
print "#{clzz.cls_name}============\n"
attrs = clzz.attrs
attrs.each do |attr|
puts attr.type + "=" + attr.name
end
end
end
def print_cls_import(i)
template = "package #{ARGV[2]};\n"
template += "\n"
template += "import android.os.Parcel;\n"
template += "import android.os.Parcelable;\n"
template += "import com.google.gson.annotations.SerializedName;\n"
if (i == 1)
template += "import java.util.List;\n"
end
template += "\n"
template
end
def print_cls_head(i)
clazz = $env.clz_list[i]
lead_clz_names = clazz.lead_cls_names
lead_num = lead_clz_names.size
cls_name = clazz.cls_name
cls_comment = clazz.cls_comment
template = "/**\n"
template += " * #{cls_comment}\n"
template += " * <p>build by AndroidBeanGen</p>\n"
template += " * <a href=\"https\://gist.github.com/pcqpcq/93675e3e02d8d44d8da3\">get it here</a>\n"
template += " */\n"
template += "public class #{cls_name} implements Parcelable {\n"
# if(i == 0)
# template += "public class #{cls_name} {\n"
# else
# template += "\n"
# template += "\t" * lead_num
# template += "public static class #{cls_name} {\n"
# end
template
end
#返回前导类的个数
def get_lead_num(i)
lead_cls_names = $env.clz_list[i].lead_cls_names
lead_num = 0
# if(lead_cls_names == nil)
# lead_num = 0
# else
# lead_num = lead_cls_names.size
# end
lead_num
end
def print_cls_end(i)
lead_num = get_lead_num(i)
template = "\t" * lead_num + "}\n\n"
template
end
def print_attrs(i)
lead_type = "\t" * get_lead_num(i) + "\t"
attrs = $env.clz_list[i].attrs
template = "\n"
attrs.each do |attr|
type = attr.type
name = attr.name
template += "#{lead_type}@SerializedName(\"#{name}\")\n"
if type == "String"
template += "#{lead_type}#{type} #{name} = \"\";\n"
else
template += "#{lead_type}#{type} #{name};\n"
end
end
template
end
def get_template(i)
clazz = $env.clz_list[i]
lead_type = "\t" * get_lead_num(i) + "\t"
template = "\n"
clazz.attrs.each do |attr|
first_cap_name = getFirstUpcase(attr.name)
template += "#{lead_type}public #{attr.type} get#{first_cap_name}() {\n"
template += "#{lead_type}\treturn #{attr.name};\n"
template += "#{lead_type}}\n\n"
end
template
end
def set_template(i)
clazz = $env.clz_list[i]
lead_type = "\t" * get_lead_num(i) + "\t"
template = ""
clazz.attrs.each do |attr|
first_cap_name = getFirstUpcase(attr.name)
template += "#{lead_type}public void set#{first_cap_name}(#{attr.type} #{attr.name}) {\n"
template += "#{lead_type}\tthis.#{attr.name} = #{attr.name};\n"
template += "#{lead_type}}\n\n"
end
template
end
def parcel_template(i)
clazz = $env.clz_list[i]
template = ""
# 输出describeContents()方法
template += "\t@Override\n"
template += "\tpublic int describeContents() {\n"
template += "\t\treturn 0;\n"
template += "\t}\n\n"
# 输出writeToParcel()方法
template += "\t@Override\n"
template += "\tpublic void writeToParcel(Parcel dest, int flags) {\n"
clazz.attrs.each do |attr|
first_type_name = getFirstUpcase(attr.type)
# 特殊处理List
if first_type_name.include? "List"
first_type_name = "List"
end
# 特殊处理实体对象
if first_type_name.include? "Entity"
first_type_name = "Parcelable"
template += "\t\tdest.write#{first_type_name}(this.#{attr.name}, flags);\n"
else
template += "\t\tdest.write#{first_type_name}(this.#{attr.name});\n"
end
end
template += "\t}\n\n"
# 输出CREATOR对象
template += "\tpublic static final Parcelable.Creator<#{clazz.cls_name}> CREATOR = new Creator<#{clazz.cls_name}>() {\n\n"
template += "\t\t@Override\n"
template += "\t\tpublic #{clazz.cls_name}[] newArray(int size) {\n"
template += "\t\t\treturn new #{clazz.cls_name}[size];\n"
template += "\t\t}\n\n"
template += "\t\t@Override\n"
template += "\t\tpublic #{clazz.cls_name} createFromParcel(Parcel source) {\n"
template_builder = ""
clazz.attrs.each do |attr|
first_cap_name = getFirstUpcase(attr.name)
first_type_name = getFirstUpcase(attr.type)
if first_type_name.include? "List"
listtype_first_index = 1+first_type_name.index('<')
listtype_name = first_type_name[listtype_first_index..first_type_name.size-2]
template += "\t\t\tArrayList<#{listtype_name}> #{attr.name} = new ArrayList<#{listtype_name}>();\n"
template += "\t\t\tsource.readList(#{attr.name}, #{listtype_name}.class.getClassLoader());\n\n"
elsif first_type_name.include? "Entity"
template += "\t\t\t#{attr.type} #{attr.name} = source.readParcelable(#{attr.type}.class.getClassLoader());\n"
else
template += "\t\t\t#{attr.type} #{attr.name} = source.read#{first_type_name}();\n"
end
template_builder += "\t\t\t\t\t.set#{first_cap_name}(#{attr.name})\n"
end
template += "\n\t\t\treturn new Builder()\n"
template += template_builder
template += "\t\t\t\t\t.get#{clazz.cls_name}();\n"
template += "\t\t}\n"
template += "\t};\n\n"
template
end
def builder_template(i=0)
clazz = $env.clz_list[i]
cls_name = clazz.cls_name
instance_name = getFirstDowncase(cls_name)
attrs = clazz.attrs
lead_type = "\t" * get_lead_num(i) + "\t"
template = "#{lead_type}public static class Builder {\n\n"
template += "#{lead_type}\tprivate #{cls_name} #{instance_name} = new #{cls_name}();\n\n"
attrs.each do |attr|
first_cap_name = getFirstUpcase(attr.name)
template += "#{lead_type}\tpublic Builder set#{first_cap_name}(#{attr.type} #{attr.name}) {\n"
template += "#{lead_type}\t\t#{instance_name}.#{attr.name} = #{attr.name};\n"
template += "#{lead_type}\t\treturn this;\n"
template += "#{lead_type}\t}\n\n"
end
template += "#{lead_type}\tpublic #{cls_name} get#{cls_name}() {\n"
template += "#{lead_type}\t\treturn #{instance_name};\n"
template +="#{lead_type}\t}\n"
template += "#{lead_type}}\n\n"
template
end
def genBean
clazz_list=$env.clz_list
output_path = ARGV[1]
0.upto(clazz_list.size-1) do |i|
cur_clz = clazz_list[i]
output_file = File.new("#{output_path}/#{cur_clz.cls_name}\.java", "w")
output_file.puts print_cls_import(cur_clz.cls_import_advanced)
output_file.puts print_cls_head(i)
output_file.puts print_attrs(i)
output_file.puts get_template(i)
output_file.puts set_template(i)
output_file.puts parcel_template(i)
output_file.puts builder_template(i)
output_file.puts print_cls_end(0)
output_file.close
end
end
=begin
$clz_list = [] #类的容器
$cur_clz = nil #当前类
$attr = nil #当前属性
$attr_index=0 #当前类的第几个属性
$clz_index=0 #当前属于第几个类
=end
File.open("#{ARGV[0]}", "r:UTF-8"){|f|
f.each_line do |line|
line = line.gsub("\n","") #去除换行符
if /^Cls/ =~ line #碰到以Cls开头,表名以下的属性属于该类
type_cls_names = line.split(":") #将该行分成两部分,第一部分为Cls,第二部分为类名集合,每个类名之间用-相连
cls_names = type_cls_names[1].split("-") #获取类名集合
# 类名之后的内容为类注释,尝试获取类注释,如果有的话
if type_cls_names.size > 2
cls_comment = type_cls_names[2]
$env.cur_clz_comment = cls_comment
end
cls_name = cls_names[cls_names.size-1]
$env.cur_clz = Clazz.new(cls_name)
$env.cur_clz.lead_cls_names = cls_names[0...cls_names.size-1] #获取前导类名集合
$env.clz_list[$env.clz_index] = $env.cur_clz;
$env.clz_index += 1
$env.attr_index = 0 #重置attr_index
else #将该类的属性,填充在该类中
if $env.cur_clz == nil
puts "nil"
else
attr_type_name = line.split(":")
attr_name=attr_type_name[0]
attr_type=attr_type_name[1]
$env.attr = Attr.new(attr_type,attr_name)
$env.cur_clz.attrs[$env.attr_index] = $env.attr
$env.attr_index += 1
# 如果包含List,则导入List包
if (attr_type.include? "List")
$env.cur_clz.cls_import_advanced = 1
end
# 如果当前类有注释
if $env.cur_clz_comment != nil
$env.cur_clz.cls_comment = $env.cur_clz_comment
end
end
end
end
=begin
print_clz_list
puts get_template(0)
puts builder_template
=end
genBean
}
config
Cls:StatisticsInfoDbEntity:统计信息数据库实体
id:int
pluginId:String
name:String
introduce:String
colorResName:String
iconResName:String
itemResName:String
cardResName:String
isShow:int
package master.com.tmiao.android.gamemaster.entity.db;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;
/**
* 插件信息数据库实体
* <p>build by AndroidBeanGen</p>
* <a href="https://gist.github.com/pcqpcq/93675e3e02d8d44d8da3">get it here</a>
*/
public class PluginInfoDbEntity implements Parcelable {
@SerializedName("id")
int id;
@SerializedName("pluginId")
String pluginId = "";
@SerializedName("name")
String name = "";
@SerializedName("introduce")
String introduce = "";
@SerializedName("colorResName")
String colorResName = "";
@SerializedName("iconResName")
String iconResName = "";
@SerializedName("itemResName")
String itemResName = "";
@SerializedName("cardResName")
String cardResName = "";
@SerializedName("isShow")
int isShow;
public int getId() {
return id;
}
public String getPluginId() {
return pluginId;
}
public String getName() {
return name;
}
public String getIntroduce() {
return introduce;
}
public String getColorResName() {
return colorResName;
}
public String getIconResName() {
return iconResName;
}
public String getItemResName() {
return itemResName;
}
public String getCardResName() {
return cardResName;
}
public int getIsShow() {
return isShow;
}
public void setId(int id) {
this.id = id;
}
public void setPluginId(String pluginId) {
this.pluginId = pluginId;
}
public void setName(String name) {
this.name = name;
}
public void setIntroduce(String introduce) {
this.introduce = introduce;
}
public void setColorResName(String colorResName) {
this.colorResName = colorResName;
}
public void setIconResName(String iconResName) {
this.iconResName = iconResName;
}
public void setItemResName(String itemResName) {
this.itemResName = itemResName;
}
public void setCardResName(String cardResName) {
this.cardResName = cardResName;
}
public void setIsShow(int isShow) {
this.isShow = isShow;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.pluginId);
dest.writeString(this.name);
dest.writeString(this.introduce);
dest.writeString(this.colorResName);
dest.writeString(this.iconResName);
dest.writeString(this.itemResName);
dest.writeString(this.cardResName);
dest.writeInt(this.isShow);
}
public static final Creator<PluginInfoDbEntity> CREATOR = new Creator<PluginInfoDbEntity>() {
@Override
public PluginInfoDbEntity[] newArray(int size) {
return new PluginInfoDbEntity[size];
}
@Override
public PluginInfoDbEntity createFromParcel(Parcel source) {
int id = source.readInt();
String pluginId = source.readString();
String name = source.readString();
String introduce = source.readString();
String colorResName = source.readString();
String iconResName = source.readString();
String itemResName = source.readString();
String cardResName = source.readString();
int isShow = source.readInt();
return new Builder()
.setId(id)
.setPluginId(pluginId)
.setName(name)
.setIntroduce(introduce)
.setColorResName(colorResName)
.setIconResName(iconResName)
.setItemResName(itemResName)
.setCardResName(cardResName)
.setIsShow(isShow)
.getPluginInfoDbEntity();
}
};
public static class Builder {
private PluginInfoDbEntity pluginInfoDbEntity = new PluginInfoDbEntity();
public Builder setId(int id) {
pluginInfoDbEntity.id = id;
return this;
}
public Builder setPluginId(String pluginId) {
pluginInfoDbEntity.pluginId = pluginId;
return this;
}
public Builder setName(String name) {
pluginInfoDbEntity.name = name;
return this;
}
public Builder setIntroduce(String introduce) {
pluginInfoDbEntity.introduce = introduce;
return this;
}
public Builder setColorResName(String colorResName) {
pluginInfoDbEntity.colorResName = colorResName;
return this;
}
public Builder setIconResName(String iconResName) {
pluginInfoDbEntity.iconResName = iconResName;
return this;
}
public Builder setItemResName(String itemResName) {
pluginInfoDbEntity.itemResName = itemResName;
return this;
}
public Builder setCardResName(String cardResName) {
pluginInfoDbEntity.cardResName = cardResName;
return this;
}
public Builder setIsShow(int isShow) {
pluginInfoDbEntity.isShow = isShow;
return this;
}
public PluginInfoDbEntity getPluginInfoDbEntity() {
return pluginInfoDbEntity;
}
}
}
Android技术分享
By Joker
Android技术分享
- 1,232