Android 杂记

生产APK:
1、点击“Build”——“build(Rebuild) project”
2、打开项目所在目录下的“build”——“outputs”——“apk”——“debug”——“app-debug.apk”
3、由于没有创建规范的key,所以不能生成正式的APK,暂时不忙研究

interface:
目标类继承interface以确定是哪个context在调用
调用的activity需要定义为implements my_interface调用之前要new一下class(在class里面重载该类),就不用设置为static


比如:B类调用A类的接口C
A类 implements C//这个地方把A和C合并了,可以直接传递给B的接收函数
    定义 B = new B(C接口)
    操作函数()
B类
    定义B(C接口)//接收方法
    C.接口函数()//调用接口操作A类
C接口
    接口函数()

总结起来就是把接口和活动合并,方便传递接口
通过接收方法,把接口传递到要使用接口的类里面,调用接口就调用了操作函数

MVP设计模式:

Model层(模型) + View层(视图) + presenter层(业务逻辑层)

Model模型:类似实体类,json_bean这种类型的实体属性类(或其它能提供数据的类),通过接口给属性赋值或获取属性信息。
View视图:界面的展示,控件的展示和操作。
presenter业务逻辑:实现模型和视图的解耦,通过调用接口分别对模型和视图进行操作,并且模型和视图之间只能通过逻辑层进行交互,VIEW不能直接访问Model
说简单点就是
V通过调用P的接口操作P,来调用P里面操作M的接口来调用或操作M。

MVP模式的优点:
模型与视图完全分离,我们可以修改视图而不影响模型
所有的交互都发生在一个地方——Presenter内部,可以更高效地使用模型
可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁
如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)


MVP模式的缺点:
由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。比如说,原本用来呈现Html的Presenter现在也需要用于呈现Pdf了,那么视图很有可能也需要变更。

总结:
V层和M层不能直接通信,需要通过P层逻辑判断后才能传递信息,传递的方式只能是接口。
比如:

V类 implements V接口
    P p= new P(V接口)//定义P接口,需要数据的时候调用接口就行
    V_fun(data){       //V接口对应的各种方法
      View.settext(data);
    }
    onclick{           //触发P类中的方法
      p.fun()
    } 
M类(user.class) implements M接口
        public M()//重载类,方便P类New一个M接口
        M_fun()
P类 implements P接口
    M接口 m;
    P接口 p;
    public P(V接口){//重载类,方便V类New一个P接口,并将V接口传递给M类
      p = V接口;    //传递V接口到P类
      m = new user();  //通过M类实例化M接口(注意不是M类,因为定义的m是M接口类型)
    }
    public fun(){   //P中的逻辑操作方法,用于V类调用
      data = m.v_fun();//通过M接口获取数据
      V接口.v_fun(data);//通过V接口传递数据并操作View
    }

V接口
    v_fun()
M接口
    M_fun()
P接口
    P_m_fun()
    P_v_fun()
    fun()
使用:

fragment:
用getFragmentManager.beginTransaction().replace(fragment1.getId(), f1).commit()显示
用fragmentTransaction.hide(f1);隐藏
其中fragment1.getId()是XML中的ID号
f1是自定义的fragment

GSON:

创建JSON格式类 jsonbean
生产json数据类:
Gson gson = new Gson();
jsonbean my_jsonbean = gson.fromjson(jsonstring,jsonbean)
生产json字符串:
Gson gson = new Gson();
String my_jsonstring = gson.tojson(my_jsonbean)

简单GSON 不用建立对应的bean_class
调用系统自带的JSONObject,通过对LIST<hashmap>的访问类型就可以了
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");


EventBus:
信号接受页需要注册:EventBus.getDefault().register(this);
信号接受页需要定义接受函数:
必须在函数前标记:@Subscribe,函数名必须为onEvent
@Subscribe
    public void onEvent(String str) {
        myText.setText(str);
    };
其中的参数可以为任意event,比如一个类

OkHttp:
只能在子线程使用response获取数据,在主线程使用会报错误NetWorkOnMainThreadException
OkHttpRequest okHttpRequest = new OkHttpRequest();
get:发送后获取返回值,一般目的是从服务器获取信息
accessToken = okHttpRequest.get(accessTokenUrl);
post:发送后获取返回值,一般目的是把信息发送到服务器
data_json = okHttpRequest.post(accessTokenUrl,search_json);
post和get差不多,只是post可以携带需要传输的数据(也可以是文件,文件需要封装)
企业微信的查询就需要携带查询的Json数据(含起始时间,人员名单等)
文件上传:
文件下载:


SQLServer:
添加jtds Jar包到libs后需要点击右键,选择“add as library”


SQLITE:
查询是否存在某数据表:
db = DBHelper.getWritableDatabase();
cursor = db.rawQuery("select name from sqlite_master where type='table' ", null);
遍历查询该表是否存在于查询结果
    while (cursor.moveToNext()) {
                //遍历出表名
                String name = cursor.getString(0);
                if (name.equals(table_name)) {
                    checked = true;
                }
            } 
其中db.rawQuery可执行所有的查询语句(删减查改)

ButterKnife:
软件版本很重要,Android studio 4.1版本需要打开C:\Users\chenyong\AppData\Local\Google\AndroidStudio4.1\plugins目录,把Jar包拷贝到studio的安装目录下的plugins文件夹
同时需要添加lombok依赖,因为自动生成的json.class是通过lombok简化了的

RxJava:
Observable:被观察者
Observer:观察者
subscribe:订阅 observable.subscribe(observer)
观察者四个活动:
public void onSubscribe(Disposable d)具体不清楚,可能是初始化的活动
public void onNext(String s)通过(Observable:被观察者)调用,执行新的操作,实现线程之间的转换
public void onError(Throwable e)(Observable:被观察者)调用过程中出现错误,触发该活动
public void onComplete()(Observable:被观察者)调用过程结束后触发该活动
其中onError和onComplete必须有且只有一个,且要放在序列的最后
综上,感觉最重要的还是onNext活动,实现线程之间的活动传递,其它的都是为它做辅助工作

subscribeOn(Schedulers.newThread())定义(Observable:被观察者)中的subscribe(ObservableEmitter<String> emitter)在哪个线程中执行
observeOn(AndroidSchedulers.mainThread())定义(Observer:观察者)中的活动在哪个线程中执行
subscribe(new Observer<String>()定时(Observer:观察者)的具体活动

RxJava中定义的四种线程:
Schedulers.newThread(): 总是启用新线程,并在新线程执行操作。
Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler,不要把计算放进该线程,否则等待的时间会创建不必要的线程。
Schedulers.computation(): 计算时所使用的 Scheduler,不要把I/O放进该线程,否则等待信息反馈的时间会浪费CPU。
AndroidSchedulers.mainThread(),它指定的操作将在 Android 主线程运行

runOnUiThread(new Runnable() {
                           
 @Override
                            
public void run() {
                                
Toast.makeText(getApplicationContext(), "FourActivity2 click button", Toast.LENGTH_SHORT).show();
                            }
                       
 });


Retrofit:

//GET 接口
@GET(Constant.UrlOrigin.get_post_info)
Observable<PostInfo> getPostInfoRx(@Query("corpid") String corpid, @Query("corpsecret") String corpsecret);

//先封装一个object类
List<String> lv = new ArrayList<String>();
lv.add("ChenYong");
post_json pj = new post_json(3,starttime, endtime,lv);

//初始化retrofit

//            把数据通过message和handler传递到主线程
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.SERVER_DATA_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
                .client(RetrofitUtils.getOkHttpClient()) // 打印请求参数
                .build();
        RetrofitService service = retrofit.create(RetrofitService.class);
        Observable<wxkq> observable = service.getPostInfoRx2(Access_token,pj);


//Post 接口,使用@Body上传一个实体类(json.class)
public abstract  interface RetrofitService

@POST(Constant.UrlOrigin2.get_post_info)
Observable<wxkq> getPostInfoRx2(@Query("access_token") String access_token, @Body post_json pj);

gilde:
public void change_pic(Context context,String Url){
        Glide.with(context).load(Url).
                thumbnail(Glide.with(context).load(R.drawable.ic_launcher)).//加载图片等待过程显示的东西
                diskCacheStrategy(DiskCacheStrategy.SOURCE).//加载图片失败显示的东西
                fitCenter().
                into(new SimpleTarget<GlideDrawable>() {
                    @Override
                    public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                        if (resource.isAnimated()) {
                            resource.setLoopCount(GifDrawable.LOOP_FOREVER);//设置的重复次数,-1为一直循环,0为不循环,正整数就是循环次数
                            resource.start();//启动动画,停止用stop
                        }
                    }
                });


Dagger:
rebuild projects 过后没有生成dagger开头的文件(在build——generated——source里面没有东西),可以在ap-generated-sources里面找。

@Provides 标记为dagger实例
@Component 依赖到某个实例集合
@Inject 引用实例


思路:
新建一个接口MainComponent,设置Component,把Provides(module里面)绑定到MainActivity。
rebuild一下项目
在MainActivity里面添加依赖DaggerMainComponent.create().inject(this);
把MainActivity通过set函数传递到prensenter,在presenter里面通过MainActivity来操作View

bulid显示乱码:
打开help——edit custom vm options——添加代码“-Dfile.encoding=UTF-8”
选择file——invalidata caches/restart

ViewHolder逻辑
1、定义一个静态类,并在类里面申明变量

static class ViewHolder{
  TextView textview1;
  ImageView imageview1;
}

2、在作用域内声明一个实例化的ViewHolder
ViewHolder my_ViewHolder = new ViewHolder();

3、在作用域内赋值或调用ViewHolder里面的参数
my_ViewHolder.textview1 = (TextView)findViewById(R.id.text1)
my_ViewHolder.textview1.setText("123");


//  通过Context获取Activity
    public static Activity getActivityByContext(Context context){
        while(context instanceof ContextWrapper){
            if(context instanceof Activity){
                return (Activity) context;
            }
            context = ((ContextWrapper) context).getBaseContext();
        }
        return null;
    }


//  通过ID获取View
    @SuppressWarnings("unchecked")
     public <T extends View> T getView(int id) {
        T result = (T) getActivityByContext(context).findViewById(id);
            if (result == null) {
            throw new IllegalArgumentException("view 0x" + Integer.toHexString(id)
                + " doesn't exist");
            }
         return result;
    }


//拨打电话核心代码
//首先要取得android.permission.CALL_PHONE权限
    public void call_phone(String phone_number){
        Intent my_call_intent = new Intent("android.intent.action.CALL",Uri.parse("tel:"+phone_number));
        startActivity(my_call_intent);
    }

//发送短信核心代码
//首先要取得android.permission.CALL_PHONE和android.permission.SEND_MSS权限
    public void send_msm(String phone_number,String send_data){
    try{
        Intent my_send_intent = new Intent(Intent.ACTION_VIEW);
        my_send_intent .putExtra("address",phone_number);
        my_send_intent .setData(Uri.parse("smsto:"+tel));
        my_send_intent .putExtra("sms_body",send_data);
        my_send_intent .setType("vnd.android-dir/mms-sms");
        startActivity(my_send_intent);
        
    }
    catch(ex e){}
    }
或者    SmsManager smsManager = SmsManager.getDefault();
    smsManager.sendTextMessage(phone_number,null,send_data,null,null);


// Activity之间传递消息(需要finish)
//思路:建立公有静态类,不需要实例化

public class m_change_flag {
    static boolean change_flag = false;
    public static void save_flag(boolean change_flag1){
        change_flag =change_flag1;
    }
    public static boolean get_flag(){
        return change_flag;
    }
}
//在Activity加载时调用m_change_flag.get_flag加载数据
//在Activity结束时调用m_change_flag.save_flag保存数据

隐藏的activity
第一步,设置manifest里面的activity属性
android:theme="@android:style/Theme.Translucent.NoTitleBar"//隐藏界面
android:launchMode="singleInstance"//独占模式打开(始终只打开1个界面,如果已打开则不执行打开操作)
android:windowSoftInputMode="adjustResize"//界面缩放(有键盘或其它界面,该界面上的控件会自动缩放或调整位置)

第二步:在activity中执行
moveTaskToBack(true);//使界面回到HOME界面(软件icon所在的桌面界面)


或第二步:在activity中执行
intent=new Intent(Intent.ACTION_MAIN);//指定跳到系统桌面,*ACTION_MAIN:应用程序入口点
                
intent.addCategory(Intent.CATEGORY_HOME);//*CATEGORY_HOME:随系统启动而运行
                
//setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //清除上一步缓存
                
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//*FLAG_ACTIVITY_NEW_TASK:默认的跳转类型,会重新创建一个新的Activity
                
startActivity(intent);
//使软件回到手机开机默认显示的桌面界面

基础知识

判断字符串是否为空
 if (TextUtils.isEmpty(str)) {//判断字符串为空
            return null;
        }


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值