Note | 研发录之重构

一、重构项目结构

Step 1. 自定义业务无关的基础类库

  • com.baselib.activity: 封装业务无关的公用逻辑,如后面的BaseActivity代码
  • com.baselib.cache: 缓存数据和图片的处理
  • com.baselib.net: 网络底层封装库
  • com.baselib.ui: 自定义控件
  • com.baselib.utils: 业务无关的公用方法

Step 2. 实际项目中类进行归类划分

  • com.myapp.activity: 所有的Activity,其他三大组件同样如此
  • com.myapp.adapter: 所有的适配器
  • com.myapp.entity: 实体类
  • com.myapp.db: SQLite相关的逻辑封装
  • com.myapp.engine: 业务相关的类
  • com.myapp.ui: 自定义控件
  • com.myapp.utils: 工具类
  • com.myapp.interfaces: 接口,以I作为开头
  • com.myapp.listener: 基于Listener的接口,命名以On作为开头

二、Activity 模板

1. com.baselib.activity.BaseActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class BaseActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initVariables();
initViews(savedInstanceState);
loadData();
}
// 初始化变量,包括Intent带的数据和Activity内的变量
protected abstract void initVariables();
// 加载layout布局文件,初始化控件,为控件挂上事件方法
protected abstract void initViews(Bundle savedInstanceState);
// 获取数据
protected abstract void loadData();
}

2. com.myapp.activity.LoginActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class LoginActivity extends BaseActivity {
private int loginTimes;
private String strEmail;
private EditText etPassword;
private EditText etEmail;
private Button btnLogin;
@Override
protected void initVariables() {
loginTimes = -1;
Bundle bundle = getIntent().getExtras();
strEmail = bundle.getString(AppConstants.Email);
}
protected void initViews(Bundle savedInstanceState) {
setContentView(R.layout.activity_login);
etEmail = (EditText) findViewById(R.id.email);
etEmail.setText(strEmail);
etPassword = (EditText) findViewById(R.id.password);
// 登录事件
btnLogin = (Button) findViewById(R.id.sign_in_button);
btnLogin.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
gotoLoginActivity();
}
});
}
private void gotoLoginActivity() {
startActivity(new Intent(LoginActivity.this, PersonCenterActivity.class));
}
@Override
protected void loadData() {
loadWeatherData();
loadCityData();
}
...
}

三、Adapter 模板

com.myapp.adapter.WeatherAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class WeatherAdapter extends BaseAdapter {
private final ArrayList<WeatherInfo> weatherList;
private final BaseActivity context;
public WeatherAdapter(ArrayList<WeatherInfo> weatherList, BaseActivity context) {
this.weatherList = weatherList;
this.context = context;
}
public int getCount() {
return weatherList.size();
}
public WeatherInfo getItem(final int position) {
return weatherList.get(position);
}
public long getItemId(final int position) {
return position;
}
public View getView(final int position, View convertView, final ViewGroup parent) {
final Holder holder;
if (convertView == null) {
holder = new Holder();
convertView = context.getLayoutInflater().inflate(R.layout.item_weatherlist, null);
holder.tvCity = (TextView) convertView.findViewById(R.id.tvCity);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
WeatherInfo weatherInfo = weatherList.get(position);
holder.tvCity.setText(weatherInfo.getCity());
return convertView;
}
class Holder {
TextView tvCity;
}
}

ListDemoActivity.onCreate()

1
2
3
4
5
6
7
8
9
10
lvWeatherList = (ListView) findViewById(R.id.lvWeatherlist);
WeatherAdapter adapter = new WeatherAdapter(weatherList, ListDemoActivity.this);
lvWeatherList.setAdapter(adapter);
lvWeatherList.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// do something...
}
});

四、实体化编程

1. JSON 数据

1
2
3
4
5
6
7
8
9
{ "weatherinfo":{
"city":"北京",
"cityid":"101010100",
"temp":"24",
"WD":"南风",
"SD":"74%",
"time":"17:45"
}
}

2. 生成实体类

可以使用插件,也可以使用公开的工具,如包建强提供的实体生成器下载地址

3. 序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Weatherinfo implements Serializable {
private static final long serialVersionUID = 1L;
private String city;
private String cityid;
private String temp;
private String WD;
private String SD;
private String time;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
...
}

4. fastJSON

1
2
3
4
5
WeatherEntity weatherEntity = JSON.parseObject(jsonContent, WeatherEntity.class);
WeatherInfor weatherInfor = weatherEntity.getWeatherInfo();
if (weatherInfor != null) {
tvCity.setText(weatherInfo.getCity());
}

如果使用崩溃,试下在混淆文件中加以下两行:

1
2
-keepattributes Signature // 避免混淆泛型
-keepattributes *Annotation* // 不混淆注解

5. 传递

1
intent.putExtra(AppContants.Weather, weatherInfo);

五、类型安全转换函数

valueOf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public final static int convertToInt(Object value, int defaultValue) {
if (value == null || "".equals(value.toString().trim())) {
return defaultValue;
}
try {
return Integer.valueOf(value.toString());
} catch (Exception e) {
try {
return Double.valueOf(value.toString()).intValue();
} catch (Exception e) {
return defaultValue;
}
}
}

substring

1
2
3
4
5
String cityName = "T";
String firstLetter = "";
if (cityName.length() > 1) {
firstLetter = cityName.substring(1, 2);
}