自学 android

试了两天,不管是deepin 软件仓库自带的eclipse,还是java 版的idea,怎样安装android 都不成功,反正各样的错误。最后到android官网下载了最新的集成开发软件才成功。官网网址

https://developer.android.com/studio     下载了linux 版:android-studio-2022.2.1.20-linux.tar.gz

按照安装文档轻松安装。建议,最好让电脑科学上网,因为有很多个文件是从google网站上下载的。

还有最好不要用虚拟终端输出程序结果。因为速度很慢。找一个旧手机代替,速度快得多。

下面的代码是输入框的内容显示在文本框中。

以下的程序都采用的是Empty Views Activity 模板。

发现android编程,ui界面部分只要把布局编辑器练熟就行了,难的还是代码的事件处理部份。ui的很多控件初学都用不上,只要把三四个常用的搞熟就可以练代码了。

package com.example.wz;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);    //按照布局文件activity_main.xml 显示,估计此方法是不停刷新此文件的内容,所以程序不用再setContentView

        Button button=findViewById(R.id.button2);          //android 用findViewById 取得java的控件实例
        EditText editText=findViewById(R.id.editTextText);  //editText 对应的布局编译器中为Plain Text   文本输入框
        TextView textView=findViewById(R.id.textView3);

        button.setOnClickListener(view -> {                 //按键的响应
            String s = String.valueOf(editText.getText());   //取文本框输入内容
            textView.setText(s);
        });
    }
}

如要连接网络,必须在AndroidManifest.xml文件中加上此两句

下面的代码是连接服务器

package com.example.wz;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);    //按照布局文件activity_main.xml 显示,估计此方法是不停刷新此文件的内容,所以程序多次setContentView()。

        Button button=findViewById(R.id.button2);          //android 用findViewById 取得java的控件实例
        EditText editText=findViewById(R.id.editTextText);  //editText 对应的布局编译器中为Plain Text   文本输入框
        TextView textView=findViewById(R.id.textView3);

        button.setOnClickListener(view -> {                 //按键的响应
        //    String s = String.valueOf(editText.getText());   //取文本框输入内容
        //   textView.setText("接收数据");
            try {
                Socket socket=new Socket("192.168.43.61",3000);
                InputStream inputStream=socket.getInputStream();
                ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
               String s=objectInputStream.readUTF();
                textView.setText(s);
               socket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        });
    }
}

注意:try  catch语句要注释掉throw new RunimeException(e);这句,否则一有错,程序就退出。有这个基础程序框架,就可以试试把java程序搬到手机上。

还有setContentView()方法,估计安卓系统是定时不停地刷新桌面显示控件,有点像java的Timer,所以程序不用多次用此方法,一次就行了。

android 线程间传递数据,不能用java 线程的传递方法,如静态类变量就不能用。

package com.example.wz;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {
    static Handler handler;
    static TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        EditText editText = findViewById(R.id.editTextText);
        textView = findViewById(R.id.textView);

        Handler.Callback hc=new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {     //这里必须调用handle类的镶嵌类Handle.Callback的handleMessage方法。
                int t=msg.arg1;
                textView.setText(String.valueOf(t));
                return false;
            }
        };
        handler =new Handler(Looper.myLooper(),hc);
        button.setOnClickListener(view -> {
            Th th = new Th();
            th.start();
        });
    }
}
class Th extends Thread {
        int t=0;
        public void run() {
            while (true) {
                Message message = new Message();
                message.arg1=t;
                MainActivity.handler.sendMessage(message);
                t++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    //         throw new RuntimeException(e);
                }
            }
        }
}




此种传递数据的方法,数据的产生和ui显示是异步的。我理解有点像map 的键值对,这个ss就是键,接照键的对应关系,线程先把值存在”map”中,ui再取出此值显示。这样理解好记忆。

安卓的主线程只能处现ui代码和事件响应代码,其他的java逻辑算法代码都不能放在主线程中,java代码只能放在响应事件的代码块中,或者放在其他子线程中。而且响应事件的代码耗时不能太久,更不能放循环等待的语句,如有这种耗时的代码,必须放在新线程中,用事件响应启动此线程。如按钮单击启动耗时线程。

其实这也是一个android编程通用方法,把ui代码放在主线程中,其他的一切逻辑代码另开一个线程完成,主线程用一个事件响应启动这个新线程,新线程的数据通过上面程序的方法传给主线程完成显示。

看jdk学Handle

Handler 允许您发送和处理Message与线程关联的 Runnable 对象MessageQueue。每个 Handler 实例都与一个线程和该线程的消息队列相关联。当您创建一个新的处理程序时,它会绑定到一个Looper. 它会将消息和可运行对象传递到该 Looper 的消息队列,并在该 Looper 的线程上执行它们。

Handler 有两个主要用途:(1) 安排消息和可运行对象在未来某个时间点执行;(2) 将要在与您自己的线程不同的线程上执行的操作排队。

调度消息是通过 post(Runnable)postAtTime(java.lang.Runnable, long)、 postDelayed(Runnable, Object, long)sendEmptyMessage(int)、 sendMessage(Message)sendMessageAtTime(Message, long)和 sendMessageDelayed(Message, long)方法完成的。post版本允许您将 Runnable 对象入队,以便在接收到消息队列时调用它们sendMessage版本允许您将包含将由MessageHandler 的方法处理的数据包的对象排入队列handleMessage(Message)(要求您实现 Handler 的子类)。

发布或发送到处理程序时,您可以允许项目在消息队列准备就绪后立即处理,或者指定处理前的延迟或处理的绝对时间。后两者允许您实现超时、滴答和其他基于时间的行为。

handle post() 方法,发现只能更新一次,不知道是否正确

此方法代码很简单

package com.example.wz;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {
    static Handler handler=new Handler();
    static TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        EditText editText = findViewById(R.id.editTextText);
        textView = findViewById(R.id.textView);

        button.setOnClickListener(view -> {
            Th th = new Th();
            th.start();
        });
    }
}
class Th extends Thread {
        public void run() {
             MainActivity.handler.post(()->{
                 MainActivity.textView.setText("hello nanning");
             });
        }
}




这里的handle实例必须放在主线程中,其实把它想成java场景中的静态类变量就好理解了。

如要循环,可以这样处理,但又不能加Thread.sleep()延时

  class Th extends Thread {                       //刚实验,此post方法只能更新一次ui。如加循环,报错
                public void run () {
                    while(true) {
                        h.post(new Runnable() {
                            public void run() {
                                textView.setText(String.valueOf(1));
                            }
                        });
                            h.post(new Runnable() {
                                public void run() {
                                    textView.setText(String.valueOf(2));
                                }
                            });
                    }
            }
        }

这个post方法虽然只能执行一次更新ui,也可编写许多场景的程序了。如连接服务器一次读取数据,输入网址读取网页文件,查询一次文件目录,如是线程不停传递数据则不能用此方法。

利用handle.post()连接服务器读取一次数据

package com.example.wz;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {
    static Handler h = new Handler();
    static TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        EditText editText = findViewById(R.id.editTextText);
        textView = findViewById(R.id.textView);

        button.setOnClickListener(view -> {
            Th th = new Th();
            th.start();
        });
    }
}
class Th extends Thread {                      //刚实验,此post方法只能更新一次ui。如加循环,报错
    public void run() {
        Socket socket= null;
        String s;
        try {
            socket = new Socket("192.168.2.8",3000);
            InputStream inputStream=socket.getInputStream();
            ObjectInputStream objectInputStream=new 
            ObjectInputStream(inputStream);
            s=objectInputStream.readUTF();
            MainActivity.h.post(new Runnable() {
            public void run() {
                MainActivity.textView.setText(s);
            }
        });
            objectInputStream.close();
        } catch (IOException e) {
            //      throw new RuntimeException(e);
        }
    }
}


手机要是上网,必须要在全局文件中加这俩句


=========================================================================

android  文件

参考出处:https://blog.csdn.net/huweiliyi/category_8913738.html

raw目录
asserts目录
data/data/包名
sdcard目录
其中raw下的和asserts下的文件可以以资源文件的形式读取,这些目录的数据只能读取,不能写入,两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
data/data/包名和sdcard目录文件可读可写。其中data/data/包名目录不需要申请权限,sdcard目录需要申请权限
读取文件要在全局文件中加这两句

 
 

data/data/(包名) 目录文件读写
将数据以普通文件的形式保存在 /data/data/包名中,该方法不需要申请权限。
存放在数据区(/data/data/包名)的文件可以使用openFileOutput和openFileInput进行操作。
也可以直接指定文件/data/data/包名路径读写。
 

data/data/包名/shared_prefs    存放SharedPreferences数据 

data/data/包名/databases        存放数据库数据

data/data/包名/files            存放普通数据

data/data/包名/cache             存放缓存文件

开发IDE 右边有一个Device File  Explorer   用它可以浏览手机的整个目录结构

可以用它看/data/data/ 有啥文件,在读取。

你可能感兴趣的:(android,android,studio,java)