手机安全卫士(七)----- 接着回顾之前的代码

紧接着上一篇博客,接着复习Android的知识点。一个暑假的时间自己在学车,即使每天都看了一点点知识,但是效率不高,现在需要在图书馆里给他补起来!

第五个知识点:如何利用Handle处理

在默认情况下,Android所有的操作都在主线程中进行,对一些耗时的操作,必须开启一个子线程来处理。这就需要用到Handle,通俗点来说,就是在子线程中获取数据,数据获取完之后,handle发送“数据已经获得的消息”,然后在主线程中把这些数据在组件中展示出来。

下面是具体的用法(类似与一种框架):

首先开启一个子线程,像是从数据库中取数据,进行网络需求下载数据等等都需要进行开启子线程,

子线程中存在多种消息(多种情况)

 new Thread(){
            @Override
            public void run() {
                 msg = Message.obtain();
                 msg.what = "0101"
                 handler.sendMessage(msg);
       
            }
        }.start();
private Handler handler = new Handler(){
        public void handleMessage(Message msg){
            switch (msg.what){
                case 0101:
                    //执行相应的操作
                    break;
                case 0102:
                    //执行相应的操作
                    break;
                default:
        }
    }
}

子线程中只存在一种消息:

new Thread(){
            @Override
            public void run() {
         
                handler.sendEmptyMessage(0);
            }
 }.start();
 private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            lv_contact_items.setAdapter(new ContactAdapter());

        }
    };

Handle的使用框架就是上面的两种方式。

第六个知识点:SQLlite的使用

使用这个知识点的时候,我是真正的感觉到了书上的知识毕竟是书上的,自己写的代码是自己的写的,这还得从实践中得到真知啊!

三步走使用sqlite

第一步首先建立DBHelper,建造数据库:

public class BlackNumberDBHelper extends SQLiteOpenHelper {
    public BlackNumberDBHelper(Context context) {
        super(context,"blacknumber.db",null,1);
    }

    /**
     * 创建一个数据库表
     * @param db
     * 包含三个字段  id  phonenumber  model
     * model 0 全部拦截   1 电话拦截  2 短信拦截
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table number1 (id Integer primary key AUTOINCREMENT,phonenumber varchar(20),model varchar(2) )");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

构建这个类,首先要继承SQLiteOpenHelper类,然后最重要的就是构造方法,使用父类的构造方法,传入一个上下文参数,第二个是数据库名称,其他两个不重要,照着写就行。

第二个方法是构建一张表,这就能用到之前学的数据库的知识了,注意点就是上面的表名就是number1,在编写第二步类的时候,要与这个表名保持一致才行!!!

然后就可以执行第二步了;

第二步:写BDDao

我觉得这个类中最主要就是构造方法,忽然觉得有一种豁然开朗的感觉,非常的舒服!



public class BlackNumberDao {
    private BlackNumberDBHelper db;
    private String tablename = "number1";

    //写在构造器中   只要对象new 出来   数据库就会自动创建
    public BlackNumberDao(Context context) {
        db = new BlackNumberDBHelper(context);
    }



    public List<BlackNumberInfo> QueryAll(){

        SQLiteDatabase readableDatabase = db.getReadableDatabase();
        Cursor query = readableDatabase.query(tablename, null, null, null, null, null, null);
        while (query.moveToNext()){   
            String phone = query.getString(1);
            blackNumberInfo.setPhonenumber(phone);
            String model = query.getString(2);      
        }
        query.close();
        readableDatabase.close();
        return list;

    }



    /**
     * 往数据库中添加数据
     *
     * @param phone 电话
     * @param model 拦截模式
     */
    public Boolean Add(String phone, String model) {
        SQLiteDatabase writableDatabase = db.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("phonenumber", phone);
        Log.d("测试", "Add: "+phone);
        contentValues.put("model", model);
        //如果insert的值位-1   则说明插入失败
        long insert = writableDatabase.insert(tablename, null, contentValues);
        writableDatabase.close();
        //如果插入进数据库 则返回true
        if (insert != -1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 删除数据库中的数据
     *
     * @param phone
     * @return
     */
    public Boolean Delete(String phone) {
        SQLiteDatabase writableDatabase = db.getWritableDatabase();
        //返回值为0 说明没有删除数据
        int delete = writableDatabase.delete(tablename, "phonenumber=?", new String[]{phone});
        writableDatabase.close();
        if (delete != 0) {
            return true;
        } else {
            return false;
        }

    }

    /**
     * 更改拦截模式
     *
     * @param phone
     * @param model
     * @return
     */
    public Boolean Update(String phone, String model) {
        SQLiteDatabase writableDatabase = db.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("model", model);
        int update = writableDatabase.update(tablename, contentValues, "phonenumber=?",new String[]{phone});
        writableDatabase.close();
        if (update==0){
            return false;
        }else {
            return true;
        }

    }


    /**
     * 查找数据的操作  主要是查找phone的model
     * @param phone
     * @return
     */
    public String Query(String phone){
        String model = null;
        SQLiteDatabase readableDatabase = db.getReadableDatabase();
        Cursor query = readableDatabase.query(tablename, new String[]{"model"}, "phonenumber=?", new String[]{phone}, null, null, null);
        while (query.moveToNext()){
            model = query.getString(0);
        }
       return model;
    }


}

这个类中有个DBHelper的实例变量,恰好在构造方法中有初始化了这个实例变量,这个就能使用这个数据库了,记住这个上下文参数也要传进入,这样就可以利用这些db进行增删改查了。具体的使用方法基本就是上面这几种了。更新,删除,插入如果失败返回的是-1,因此只要判断返回的是不是-1即可。查询函数是比较难写的一个方法,因为他的参数特别多,需要加以记忆!还有就是这个SQL语句很简单,并没有涉及到很难得查询,因此那更难得查询应该怎样写,这还是一个自己没有尝试得地方。

第三步:在Activity中掉用这个DBdao即可使用:

BlackNumberDao blackNumberDao = new BlackNumberDao(getApplicationContext());
Boolean add = blackNumberDao.Add(phone, model);

这样就完成了数据库的使用,现在回想起来,使用这个数据库也挺简单的,每次看一遍代码,自己都会有新的体会!

第七个知识点:Fragment的使用

这个知识点的内容也是非常中要的,具体的重要原理咱不讲,咱只说如何使用。

用一个小小的Demo来说明如何使用Fragment:像微信的主页面那样,按下面的一张图片就跳转到一个界面,可以来回的跳转。

在做这个Demo的时候,我认为Fragment还不容易吗!!不就是利用replace和add等方法加上去不就行了,结果是,我居然搞了2个多小时,把我的激情都给搞没有了,再一次被编程打击了!!但是最终的结果还好,自己完成了这个小小的需求,自己遇到了三个错误,搞了半天。

错误一:自己把自己的Activity页面搞混了

这是一个小错误,我觉得是因为自己好多天没有学习Android所导致的,最近在写JavaWeb的东西,这个问题不大,自己看界面的错误就解决了

错误二:对于import android.app.Fragment和android.support.v4.app.Fragment的问题

我在Fragment中使用android.support.v4.app.Fragment,结果在Activity中使用import android.app.Fragment,结果是一致报错,我心想,我自己不会这么白痴吧,这点知识还能打错了,自己找了半天,才解决了这个问题,具体他们两个的区别点击这篇博客看看吧,一定要保持一致的包,这样才不会出错。

错误三:java.lang.IllegalStateException: commit already called报这个错误

到了最后了,我心想该没有错了吧,结果又给我提个错,结果百度一搜,答案就出来了,原因如下:

是因为你的ft事务是全局的变量,只能commit一次。所以用两个局部ft事务去做commit即可。

所以说,一个ft只能执行一次commit操作,而且,一定要保证ft为局部变量,否则可能会抛出这个错误,

还有一个最最最最最重要的错误,如下:下面两段代码中,这三句的

 FragmentManager fm = getFragmentManager();
 FragmentTransaction ft = fm.beginTransaction();
 Fragment fragment = null;

的作用范围是一样的吗????

    private void initEvent() {
        View.OnClickListener pagechange = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = getFragmentManager();
                FragmentTransaction ft = fm.beginTransaction();
                Fragment fragment = null;
                switch (v.getId()) {
                    case R.id.ib_home_home:
                        fragment = new HomeFragment();
                        break;
                    case R.id.ib_home_check:
                        fragment = new CheckFragment();
                        break;
                    case R.id.ib_home_myinfo:
                        fragment = new MyinfoFragment();
                        break;
                    default:
                        break;
                }
                ft.replace(R.id.home_content_fragment, fragment);
                ft.commit();
            }
        };
 private void initEvent() {
        View.OnClickListener pagechange = new View.OnClickListener() {
                 FragmentManager fm = getFragmentManager();
                FragmentTransaction ft = fm.beginTransaction();
                Fragment fragment = null;
            @Override
            public void onClick(View v) {
               
                switch (v.getId()) {
                    case R.id.ib_home_home:
                        fragment = new HomeFragment();
                        break;
                    case R.id.ib_home_check:
                        fragment = new CheckFragment();
                        break;
                    case R.id.ib_home_myinfo:
                        fragment = new MyinfoFragment();
                        break;
                    default:
                        break;
                }
                ft.replace(R.id.home_content_fragment, fragment);
                ft.commit();
            }
        };

答案是不一样的,第二种代码就会报上面那种错。(我认为第二种方式ft已经是局部变量了,但是他不是,必须是onClick种的变量才是局部变量)具体的代码我就不展示了,毕竟是一个小小的Demo,不难,但是易错点多,我辈尚需努力啊!

第八个知识点,也是我认为最难理解的知识点:ListView的使用

ListView用到是会用,但是对于一些具体的细节问题,需要进步的去理解,去慢慢的琢磨

下面就先利用简单的list做个简单的demo,再利用很多的数据做一个进阶版的Demo,就是一个用系统的,一个用自定义的item

刚写好代码就遇到一个错误,这个错误是这样的Error running HomeActivity: The activity must be exported or contain an intent-filte

怎么都运行不了了,然后到网上一搜,发现我在运行一个activity界面,并不是一个app程序:如下所示:

listview的使用也分三个步骤:

第一:首先在布局里声明ListView组件:


    <ListView
        android:id="@+id/lv_listview_demo1"
        android:divider="#000"
        android:dividerHeight="5dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

divider属性是指两个item之间的边框线的颜色 ,dividerHeight是指边框线的高度

第二步:初始化对象

这一步很简单,就是find viewbyid之类的步骤

第三步:直接利用SetAdapter就行了:

 private String [] data = new String[]{"aaa","aaa","aaa","aaa","aaa","aaa","aaa","aaa",

            "aaa","aaa","aaa","aaa","aaa","aaa","aaa","aaa","aaa"
    };
    private ListView lv_listview_demo1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initView();
        initData();
        initAnimation();
        initEvent();
    }

    private void initView() {
        setContentView(R.layout.activity_listview1);
        lv_listview_demo1  = findViewById(R.id.lv_listview_demo1);
    }

    private void initData() {
        lv_listview_demo1.setAdapter(new ArrayAdapter<String>( Listview1Activity.this,android.R.layout.simple_list_item_1,data) );

    }

    private void initAnimation() {


    }

    private void initEvent() {
        lv_listview_demo1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String res = parent.getItemAtPosition(position).toString();
                Toast.makeText(Listview1Activity.this,res,Toast.LENGTH_SHORT).show();
            }
        });

    }

这种方式的ListView是最简单的,不过也是没有进行优化的。具体的优化方式就是我不太理解的地方(开发者为什么都知道这个bug了,为什么还是不在最基本的源码部分修改这个bug呢?)

接下来就是自定义一个listview了,开始自己写吧!

在这就只给一部分代码:

 private ListView lv_listview_demo2;
    private String [] data = new String[]{"aaa","aaa","aaa","aaa","aaa","aaa","aaa","aaa",
            "aaa","aaa","aaa","aaa","aaa","aaa","aaa","aaa","aaa"
    };



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        initView();
        initData();
        initAnimation();
        initEvent();
    }

    private void initView() {
        setContentView(R.layout.activity_listview2);
        lv_listview_demo2 = findViewById(R.id.lv_listview_demo2);

    }

    private void initData() {
        lv_listview_demo2.setAdapter(new DemoAdapter());

    }

    private void initAnimation() {

    }

    private void initEvent() {

    }
public class DemoAdapter extends BaseAdapter{

    @Override
    public int getCount() {
        return data.length;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View inflate = View.inflate(getApplicationContext(), R.layout.listview_item, null);
        TextView title = inflate.findViewById(R.id.title);
        TextView content = inflate.findViewById(R.id.content);
        title.setText(data[position]);
        content.setText(data[position]);
        return inflate;
    }
}

 

像这种级别的代码,一看就会,不过对于listview,这些都不行,还得学会他的优化方式,但是这篇博客,不说关于优化的方式,因为自己还没有学的很透彻,等我理解了具体的操作方式,我准备专门写一篇博客讲述为什么要优化listview。

这篇博客就到这吧,写了一下午的博客和代码,有点累了,不过很充实,我喜欢这种感觉!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值