1.线程的几种写法
1.1继承Thread类
class MyThread extends Thread{
@Override
public void run() {
//Other code
}
}
new MyThread.start(); //Start the thread
1.2使用Runnable接口
class MyThread implements Runnable{
@Override
public void run(){
//Other code
}
MyThread myThread = new MyThread(); //创建实例
new Thread(myThread).start(); //Thread接收Runnable参数
1.3匿名类(多用)
new Thread(new Runnable() {
@Override
public void run() {
//Other code
}
}).start();
2.子线程更新UI的方法
public class MainActivity extends Activity implements View.OnClickListener{
public static final int UPDATE_TEXT = 1; //更新字段
private TextView text;
private Button changeText;
@SuppressLint("HandlerLeak")
private Handler handler = new Handler(){ //全局实例handler
public void handleMessage(Message msg){ //重写handleMessage方法
switch (msg.what){
case UPDATE_TEXT:
text.setText("Text Changed"); //主线程更新UI
break;
default:
break;
}
}
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.change_text:
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message(); //创建Message
message.what = UPDATE_TEXT; //为字段赋值
handler.sendMessage(message); //将message对象发送到handler
}
}).start();
break;
default:
break;
}
}
}
3.Android异步消息处理机制
Android异步消息处理机制由四个部分组成:Message,Handler, MessageQueue,Looper。
Message
Message为线程间传递的消息,它可以在内部携带少量信息,用于在不同线程之间交换数据。出Message的what字段外,还可用arg1和arg2带一些整型数据,用obj字段携带一个Object对象。
Handler(处理者)
用于发送与处理消息。发送消息一般是使用Handler的sendMessage()方法,而发出去的消息经过一系列辗转处理之后,会最终传递到Handler的handleMessage()方法中。
MessageQueue
用于存放所有通过Handler发送的消息。这部分消息会一直存在于消息队列中,等待被处理。每个线程只有一个MessageQueue对象。
Looper
Looper是每个线程中的MessageQueue的管家,调用Looper的loop()方法之后,就会进入到一个无线循环中,然后每当发现MessageQueue存在一条消息,就会将它取出,并传送到Handler的handleMessage()方法中。每个线程也只有一个Looper对象。
4.蓝牙
蓝牙不仅要开两个常用权限,而且还要开位置权限,不然搜索不到设备。
<uses-permission android:name = "android.permission.ACCESS_COARSE_LOCATION"/>
5.Handler更新UI的用法
方法1:
//在主线程中 new Handler,就会在主线程中进行后续处理
private Handler handler = new Handler();
public void click(View v){
new Thread(new Runnable(){
@Override
public void run(){
final String result = NetUtil.get("Http://www.baidu.com");
handler.post(new Runnable(){
@Override
public void run(){
textView.setText(result); //主线程更新UI
}
});
}
}).start();
}
方法2:
private Handler handler = new Handler(){
//接收消息
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
//处理消息
String result = (String)msg.obj;
textView.setText(result);
}
};
public void click(View v){ //创建子线程并开启
new Thread(new Runnable(){
@Override
public void run(){
final String result = NetUtil.get("Http://www.baidu.com");
Message message = new Message();
message.obj = result; //设置数据
handler.sendMessage(message); //发送消息(子线程)
}
}).start();
}
Message是线程之间传递的消息,它可以在内部传递消息,主要用于不同线程之间进行数据交换。message.obj可以传递一个object对象,setData()可以设置传递的数据(可以传入Bundle对象,通过bundle.putString()可以加入数据),message.what是一个int类型,一般用来标记消息类型;arg1 和 arg2 两个int类型参数可以传递少量数据。
6.Activity重启
一些设备配置在运行过程中可能会发生改变,比如屏幕横向布局、键盘可用性和语言等;当这样的变化发生时,Android会重新启动这个正在运行的Activity,onDestroy()方法会被调用,之后onCreate()方法会被调用。这个重启的动作是为了通过自动往程序中载入可替代资源,从而适应新的配置。
7.padding与margin区别
padding用于控件内部的内容与控件边界的位置关系
margin指控件与父控件的位置关系
8.onCreate与onCreateView与onViewCreated
onCreate是指创建该fragment类似于Activity.onCreate,你可以在其中初始化除了view之外的东西
onCreateView是创建该fragment对应的视图,你必须在这里创建自己的视图并返回给调用者。如
return inflater.inflate(R.layout.fragment_settings, container, false);
(1) onViewCreated在onCreateView执行完后立即执行。
(2) onCreateView返回的就是fragment要显示的view。
9.fragment的一般写法
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button =(Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FirstFragment fragment = new FirstFragment();
Bundle bundle = new Bundle();
bundle.putString("data","传递到的数据");
fragment.setArguments(bundle);//数据传递到fragment中
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.framelayout,fragment);
fragmentTransaction.commit();
}
});
}
}
public class FirstFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first,container,false);
TextView textView = (TextView)view.findViewById(R.id.textview);
Bundle bundle =this.getArguments();//得到从Activity传来的数据
String mess = null;
if(bundle!=null){
mess = bundle.getString("data");
}
textView.setText(mess);
return view;
}
}
10.MQTT项目配置
添加依赖
repositories {
google()
jcenter()
maven {
url "https://repo.eclipse.org/content/repositories/paho-releases/"
}
}
注意下面的版本,版本号不对会失败。有的帖子是service.1.1.0但是不行。
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
之后Manifest中注册服务:
<service android:name="org.eclipse.paho.android.service.MqttService" />
11.Fragment用法
public class TitleFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance){
View view = inflater.inflate(R.layout.fragment_title, null);
RelativeLayout layout = (RelativeLayout) view.findViewById(R.id.changeButton);
layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "***", Toast.LENGTH_LONG).show();
}
});
return view;
}
}
Fragment需要返回一个view,而inflate方法可以将xml文件转换为view对象。如果要使用Fragment中的控件,需要将Activity与Fragment的内容关联,从中获取控件的对象,见上述代码的按钮监听方法。
其他:
1.将FrameLayout替换成Fragment
2..耗时操作使用handler来处理,比如更新UI,网络相关的操作等。
3.更新TextView的UI传入的参数是字符串!!!如果传整数就会炸。更新的控件要在当个布局中能够找得到。
textView.setText(count + "%"); //主线程更新UI
4.知晓当前是哪个活动
Log.d(TAG, getClass().getSimpleName());
5.项目中用到了EthernetManager的类,但是原本的Android包是没有的,许多帖子都是用了这个类来管理Ethernet。这个类是被隐藏了的,加有@hide。为了能够适用此类,看帖子说需要重新编译整个Android源码,从中拿到。这个非常费时。现从一个帖子中下载到了被隐藏类的集合。其中就有EthernetManager类。帖子:https://download.csdn.net/download/a571293251/10137493