-
Notifications
You must be signed in to change notification settings - Fork 277
知乎小报开发总结
总结在知乎小报开发的工程中遇到的问题以及相关的解决办法。
1.Intent导致的ActivityNotFoundException
无法找到对应的activity,这个异常在使用Intent启动一些系统级隐式的activity时可能会出现,例如短信、邮件、打开相机等,(还有手机没有邮件、短信app?当然有了!)如果不对这个异常进行处理的话,应用就会直接Crash。
Uri uri = Uri.parse("market://details?id="+getPackageName());
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
这个异常在开发简单翻译的过程就曾经遇到过。
-
方法1: 最佳解决方案-->在发出这个隐式Intent之前调用resolveActivity做检查
Intent intent = new Intent(Intent.ACTION_XXX); ComponentName componentName = intent.resolveActivity(getPackageManager()); if(componentName != null) { String className = componentName.getClassName(); }
-
方法2:使用try-catch捕获这个异常。
try{ // to start a mail activity code } catch (android.content.ActivityNotFoundException ex){ // catch Exception Snackbar.make(view, "No mail app found",Snackbar.LENGTH_SHORT).show(); }
2.WebView无图模式的实现
Android WebView中实现了一个方法
webView.getSettings().setBlockNetworkImage(boolean config)
官方文档解释为:
Gets whether the WebView does not load image resources from the network.
当config为true时,不加载图片,反之加载图片,而且是当url加载完成时才开始加载。
3.接口实现RecyclerView item的点击事件 RecyclerView是Google在v7包中新增的一种控件,用于代替ListView,不过它并没有基本的点击事件,所以需要我们自己为item定义点击事件。
首先需要自定义接口
public interface OnRecyclerViewOnClickListener {
void OnItemClick(View v,int position);
}
在适配器中定义接口变量
private OnRecyclerViewOnClickListener mListener;
暴露接口
public void setItemClickListener(OnRecyclerViewOnClickListener listener){
this.mListener = listener;
}
然后在onCreateViewHolder中注册点击事件
@Override
public LatestItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.latest_item_layout,parent,false);
LatestItemViewHolder holder = new LatestItemViewHolder(view,mListener);
return holder;
}
在ViewHolder中设置
public class LatestItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private OnRecyclerViewOnClickListener listener;
private CardView item;
public LatestItemViewHolder(View itemView,OnRecyclerViewOnClickListener listener) {
super(itemView);
item = (CardView) itemView.findViewById(R.id.card_view_item);
this.listener = listener;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (listener != null){
listener.OnItemClick(v,getLayoutPosition());
}
}
}
在Activity或者Fragment中使用
adapter = new LatestPostAdapter(getActivity(),list);
rvLatestNews.setAdapter(adapter);
adapter.setItemClickListener(new OnRecyclerViewOnClickListener() {
@Override
public void OnItemClick(View v, int position) {
// write code
}
});
4.横屏下Crash 由于在fragment中使用了RecyclerView,当然也就涉及到了Adapoter的使用。由于我在Adapter的构造函数中传入了Context,这直接导致了横屏下直接崩溃。
public class LatestPostAdapter extends RecyclerView.Adapter<LatestPostAdapter.LatestItemViewHolder> {
// some code
public LatestPostAdapter(Context context, List<LatestPost> list){
this.context = context;
this.list = list;
this.inflater = LayoutInflater.from(context);
}
}
我们不应该保存那些依赖Activity的数据,比如Drawable,Adapter,View或者任何与Context相关联的数据。因为上一个Activity已经没有了,如果你还要保持这些资源的引用,可能导致资源泄露。
解决的方法
-
1.简单粗暴型 直接禁止横屏,当然这只是适用于极少数的情况。可以在manifest文件中对应的activity配置:
android:screenOrientation="portrait" android:screenOrientation="landscape"
或者在Java代码中处理
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
-
2.在横屏时做相应的处理。 首先在manifest.xml文件中配置屏幕方向改变时不需要重新载入。
然后在activity中重写方法
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
5.toolbar中小箭头(返回上级activity) 好吧,这是个不算高级的问题,但是确实困扰了我一段时间。首先是怎样显示这个箭头。
private Toolbar toolbar;
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// 关键
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
怎样监听小箭头的点击事件呢?
由于箭头是位于toolbar中的控件,可以联想到应该是和onOptionsItemSelected方法有关。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
// 小箭头的id为android.R.id.home
if (id == android.R.id.home){
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
当我满怀信心写完这些代码,运行到手机上的时候,点击箭头,竟然没有返回。。。这是因为没有在manifest.xml文件中配置他的上一级activity是什么,所以也就没有返回了。配置好之后就可以正常运行了。