20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结

目录

  • 学习《Java和Android开发学习指南(第二版)》第16、19、20、22章——
  • 教材学习中的问题和解决过程
  • 代码调试中的问题和解决过程
  • [代码托管]
  • statistics.sh脚本运行结果的截图
  • 学习进度条
  • 参考资料

学习《Java和Android开发学习指南(第二版)》第16、19、20、22章——

第16章输入/输出
1.I/O操作的例子包括:
(1)创建和删除文件。
(2)从一个文件或网络套接字读取内容,或向其写入内容。
(3)把对象序列化(或保存)到持久存储中,并且获取保存的对象。
16.1文件系统和路径
1.文件系统可以包含三种类型的对象:文件、目录(也叫作文件夹)和符号链接。
2.文件系统中的一个对象,可以通过路径来唯一地标识。路径可以是绝对的或者相对的。绝对路径拥有指向文件系统中的一个对象的所有信息,相对路径并没有所需要的所有信息。在Java中,一个文件或路径是由一个java.io.File对象来表示的。
16.2 文件和目录的处理和操作
1.Files类中的read和write方法只是适用于比较小的文件。对于中等大小和较大的文件来说,使用流来代替。
16.3 输入、输出流
1.Java I/O流将Java代码和一个“数据水池”连接起来。这个“数据水池”叫做池,它可能是一个文件、一个网络套接字或者内存。
16.4 读二进制数据
1.当可用的字节数比数组的大小要小时,可以使用重载的read方法返回读取的字节数。
2.代码清单16.1 使用InputStream的compareFiles方法

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class InputStreamDemo1{
    public boolean compareFiles(Path path1,Path path2)
            throws NoSuchFileException{
        if(Files.notExists(path1)){
            throw new NoSuchFileException(path1.toString());
        }
        if(Files.notExists(path2)){
            throw new NoSuchFileException(path2.toString());
        }
        try{
            if(Files.size(path1)!=Files.size(path2)){
                return false;
            }
        }catch(IOException e){
            e.printStackTrace();
        }
        try(InputStream inputStream1=Files.newInputStream(
                path1,StandardOpenOption.READ);
            InputStream inputStream2=Files.newInputStream(
                    path2,StandardOpenOption.READ)){
            int i1,i2;
            do{
                i1=inputStream1.read();
                i2=inputStream2.read();
                if(i1!=i2){
                    return false;
                }
            }while(i1!=-1);
            return true;
        }catch(IOException e){
            return false;
        }
    }
    public static void main(String[] args){
        Path path1=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\addtwo.py");
        Path path2=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\addtwo.py");
        InputStreamDemo1 test=new InputStreamDemo1();
        try{
            if(test.compareFiles(path1,path2)){
                System.out.println("Files are identical");
            }else{
                System.out.println("Files are not identical");
            }
        }catch(NoSuchFileException e){
            e.printStackTrace();
        }
        try{
            System.out.println(Files.isSameFile(path1,path2));
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第1张图片

16.5 写二进制数据
1.代码清单16.2 OutputStreamDemo1类

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class OutputStreamDemo1{
    public void copyFiles(Path originPath,Path destinationPath)
            throws IOException{
        if(Files.notExists(originPath)
                ||Files.exists(destinationPath)){
            throw new IOException(
                    "Origin file must exist and"+
                            "Destination file must not exist");
        }
        byte[] readData=new byte[1024];
        try(InputStream inputStream=
                    Files.newInputStream(originPath,
                            StandardOpenOption.READ);
            OutputStream outputStream=
                    Files.newOutputStream(destinationPath,
                            StandardOpenOption.CREATE)){
            int i=inputStream.read(readData);
            while(i!=-1){
                outputStream.write(readData,0,i);
                i=inputStream.read(readData);
            }
        }catch(IOException e){
            throw e;
        }
    }
    public static void main(String[] args){
        OutputStreamDemo1 test=new OutputStreamDemo1();
        Path origin=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Path destination=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Destination.py");
        try{
            test.copyFiles(origin,destination);
            System.out.println("Copied Successfully");
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第2张图片

16.6.2 OutputStreamWriter
1.写入到一个OutputStreamWriter的字符,使用一个指定的字符集编码为字节。
2.代码清单16.3 使用OutputStreamWriter

package app16;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class OutputStreamWriterDemo1{
    public static void main(String[] args){
        char[] chars=new char[2];
        chars[0]='\u4F60';//representing 你
        chars[1]='\u597D';//representing 我
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Charset chineseSimplifiedCharset=
                Charset.forName("GB2312");
        try(OutputStream outputStream=
                    Files.newOutputStream(path,
                            StandardOpenOption.CREATE);
            OutputStreamWriter writer=new OutputStreamWriter(
                    outputStream,chineseSimplifiedCharset)){

            writer.write(chars);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第3张图片

16.6.3 PrintWriter

package app16;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class PrintWriterDemo1{
    public static void main(String[] args){
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Charset usAsciiCharset=Charset.forName("US-ASCII");
        try(BufferedWriter bufferedWriter=
                    Files.newBufferedWriter(path,usAsciiCharset,
                            StandardOpenOption.CREATE);
            PrintWriter printWriter=
                    new PrintWriter(bufferedWriter)){
            printWriter.println("PrintWriter is easy to use.");
            printWriter.println(1234);
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第4张图片

16.7.3 BufferedReader
1.有两点好处:
(1)包装另一个Reader,并且提供一个缓存,这将会普遍提高性能。
(2)提供另一个readLine方法来读取一行文本。

package app16;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class PrintStreamDemo1{
    public static void main(String[] args){
        Path debugFile=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        try(OutputStream outputStream=Files.newOutputStream(
            debugFile,StandardOpenOption.CREATE,
            StandardOpenOption.APPEND);
            PrintStream printStream=new PrintStream(outputStream,
            true)){
             System.setOut(printStream);
             System.out.println("To file");
            }catch(IOException e){
                     e.printStackTrace();
                 }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第5张图片

16.9 随机访问文件
1.代码清单16.8 随机访问文件

package app16;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class SeekableByteChannelDemo1{
    public static void main(String[] args){
        ByteBuffer buffer=ByteBuffer.allocate(12);
        System.out.println(buffer.position());
        buffer.putInt(10);
        System.out.println(buffer.position());
        buffer.putLong(1234567890L);
        System.out.println(buffer.position());
        buffer.rewind();
        System.out.println(buffer.getInt());
        System.out.println(buffer.getLong());
        buffer.rewind();
        System.out.println(buffer.position());

        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        System.out.println("-----------------");
        try(SeekableByteChannel byteChannel=
                    Files.newByteChannel(path,
                            StandardOpenOption.CREATE,
                            StandardOpenOption.READ,
                            StandardOpenOption.WRITE);){
            System.out.println(byteChannel.position());
            byteChannel.write(buffer);
            System.out.println(byteChannel.position());


            //read file
            ByteBuffer buffer3=ByteBuffer.allocate(40);
            byteChannel.position(0);
            byteChannel.read(buffer3);
            buffer3.rewind();
            System.out.println("get int:"+buffer3.getInt());
            System.out.println("gey long:"+buffer3.getLong());
            System.out.println(buffer3.getChar());
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第6张图片

16.10 对象序列化
1.有时我们需要将对象持久化到一个永久性存储中,以便以后能够保持并获取对象的状态。对象序列化是一种基于后进先出的方法。当序列化多个基本类型/对象的时候,先序列化的对象最后必须解序列化。
2.代码清单16.9 Customer类

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class ObjectSerializationDemo1{
    public static void main(String[] args){
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Customer customer=new Customer(1,"Joe Blog",
                 "12 West Cost");
        try(OutputStream outputStream=
            Files.newOutputStream(path,
                StandardOpenOption.CREATE);
            ObjectOutputStream oos=new
                ObjectOutputStream(outputStream)){
    //write first object
    oos.writeObject(customer);
    //write second object
    oos.writeObject("Customer info");
                }catch(IOException e){
                System.out.println("IOException");
                }
            //Deserialize
        try(InputStream inputStream=Files.newInputStream(path,
            StandardOpenOption.READ);
            ObjectInputStream ois=new
                ObjectInputStream(inputStream)){
                //read first object
             Customer customer2=(Customer)ois.readObject();
             System.out.println("First Object:");
             System.out.println(customer2.id);
             System.out.println(customer.name);
             System.out.println(customer.address);

            //read second Object
            System.out.println();
            System.out.println("Second object:");
            String info=(String) ois.readObject();
            System.out.println(info);
                }catch(ClassNotFoundException ex){//readObject still throws this exception
                        System.out.print("ClassNotFound"+ex.getMessage());                
                }catch(IOException ex2){
                    System.out.print("IOException"+ex2.getMessage());
                }
    }
}

代码清单16.10 对象序列化示例

package app16;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class ObjectSerializationDemo1{
    public static void main(String[] args){
        Path path=Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03\\code3\\Origin.py");
        Customer customer=new Customer(1,"Joe Blog",
                "12 West Cost");
        try(OutputStream outputStream=
                    Files.newOutputStream(path,
                            StandardOpenOption.CREATE);
            ObjectOutputStream oos=new
                    ObjectOutputStream(outputStream)){
            //write first object
            oos.writeObject(customer);
            //write second object
            oos.writeObject("Customer info");
        }catch(IOException e){
            System.out.println("IOException");
        }
        //Deserialize
        try(InputStream inputStream=Files.newInputStream(path,
                StandardOpenOption.READ);
            ObjectInputStream ois=new
                    ObjectInputStream(inputStream)){
            //read first object
            Customer customer2=(Customer)ois.readObject();
            System.out.println("First Object:");
            System.out.println(customer2.id);
            System.out.println(customer.name);
            System.out.println(customer.address);

            //read second Object
            System.out.println();
            System.out.println("Second object:");
            String info=(String) ois.readObject();
            System.out.println(info);
        }catch(ClassNotFoundException ex){//readObject still throws this exception
            System.out.print("ClassNotFound"+ex.getMessage());
        }catch(IOException ex2){
            System.out.print("IOException"+ex2.getMessage());
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第7张图片

16.11 本章小结
输入/输出操作在整个java.io包的成员中都得到了支持。可以通过流来读取和写入数据,而数据分为二进制数据和文本两种。此外,Java支持通过Serializable接口以及ObjectInputStream和ObjectOutputStream类进行对象序列化。

第19章线程
19.1 Java线程简介
线程是一个基本的处理单元操作系统分配处理时间就是按照线程来进行的,在一个进程中,可以有多个线程执行代码。线程有时候也叫做一个轻量级的进程,或者叫做一个执行环境。线程要消费资源。
19.2 创建一个线程
创建一个线程的方法有两种。
1.扩展java.lang.Thread类。
2.实现java.lang.Runnable接口。
19.2.1 扩展线程
1.代码清单19.1 一个简单的多线程程序

package app19;
public class ThreadDemo1 extends Thread{
    public void run(){
        for (int i=1;i<=10;i++){
            System.out.println(i);
            try{
                sleep(1000);
            }catch(InterruptedException e){
            }
        }
    }
    public static void main(String[] args){
        (new ThreadDemo1()).start();
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第8张图片

2.代码清单19.2 使用扩展了Thread的另一个类

package app19;
class MyThread extends Thread{
    public void run(){
        for(int i=1;i<=10;i++){
            System.out.println(i);
            try{
                sleep(1000);
            }catch(InterruptedException e){
            }
        }
    }
}
public class ThreadDemo2{
    public static void main(String[] args){
        MyThread thread=new MyThread();
        thread.start();
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第9张图片

19.2.2 实现Runnable
1.代码清单19.3 使用Runnable

package app19;
public class RunnableDemo1 implements Runnable{
    public void run(){
        for(int i=1;i<10;i++){
            System.out.println(i);
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
            }
        }
    }
public static void main(String[] args){
    RunnableDemo1 demo=new RunnableDemo1();
    Thread thread=new Thread(demo);
    thread.start();
}
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第10张图片

19.3 使用多线程
1.代码清单19.4 使用两个线程

package app19;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ThreadDemo3 extends JFrame{
    JLabel countUpLabel=new JLabel("Count Up");
    JLabel countDownLabel=new JLabel("Count Down");

    class CountUpThread extends Thread{
        public void run(){
            int count=1000;
            while(true){
                try{
                    sleep(100);
                }catch(InterruptedException e){
                }
                if(count==0)
                    count=1000;
                countUpLabel.setText(Integer.toString(count--));
            }
        }
    }
    class countDownThread extends Thread{
        public void run(){
            int count=0;
            while(true){
                try{
                    sleep(50);
                }catch(InterruptedException e){
                }
                if(count==1000)
                count=0;
                countDownLabel.setText(Integer.toString(count++));
            }
        }
    }
    public ThreadDemo3(String title){
        super(title);
        init();
    }
private void init(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setLayout(new FlowLayout());
    this.add(countUpLabel);
    this.add(countDownLabel);
    this.pack();
    this.setVisible(true);
    new CountUpThread().start();
    new countDownThread().start();
}
public static void constructGUI(){
    JFrame.setDefaultLookAndFeelDecorated(true);
    ThreadDemo3 frame=new ThreadDemo3("Thread Demo 3");
    
}
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
    public void run(){
    constructGUI();
    }
});
}
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第11张图片

19.4 线程优先级
1.代码清单19.5 测试线程优先级

package app19;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class ThreadPriorityDemo extends JFrame{
    JLabel counter1Label=new JLabel("Priority 10");
    JLabel counter2Label=new JLabel("Priority 1");
    class CounterThread extends Thread{
        JLabel counterLabel;
        public CounterThread(JLabel counterLabel){
            super();
            this.counterLabel=counterLabel;
        }
        public void run(){
            int count=0;
            while(true){
                try{
                    sleep(1);
                }catch(InterruptedException e){
                }
                if(count==50000)
                    count=0;
                counterLabel.setText(Integer.toString(count++));
            }
        }
    }
    public ThreadPriorityDemo(String title){
        super(title);
        init();
    }
    private void init(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new FlowLayout());
        this.add(counter1Label);
        this.add(counter2Label);
        this.pack();
        this.setVisible(true);
        CounterThread thread1=new CounterThread(counter1Label);
        thread1.setPriority(10);
        CounterThread thread2=new CounterThread(counter2Label);
        thread2.setPriority(1);
        thread2.start();
        thread1.start();
    }
    private static void constructGUI(){
        JFrame.setDefaultLookAndFeelDecorated(true);
        ThreadPriorityDemo frame=new ThreadPriorityDemo(
                "Thread Priority Demo");
    }
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                constructGUI();
            }
        });
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第12张图片

19.5 停止线程
1.代码清单19.6 停止一个线程

package app19;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class StopThreadDemo extends JFrame{
    JLabel counterLabel=new JLabel("Counter");
    JButton startButton=new JButton("Start");
    JButton stopButton=new JButton("Stop");
    CounterThread thread=null;
    boolean stopped=false;
    int count=1;
    class CounterThread extends Thread{
        public void run(){
            while(!stopped){
                try{
                    sleep(10);
                }catch(InterruptedException e){
                }
                if(count==1000){
                    count=1;
                }
                counterLabel.setText(Integer.toString(count++));
            }
        }
    }
    public StopThreadDemo(String title){
        super(title);
        init();
    }
    private void init(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setLayout(new FlowLayout());
        this.stopButton.setEnabled(false);
        startButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                StopThreadDemo.this.startButton.setEnabled(true);
                StopThreadDemo.this.stopButton.setEnabled(false);
                stopThread();
            }
        });
        this.getContentPane().add(counterLabel);
        this.getContentPane().add(startButton);
        this.getContentPane().add(stopButton);
        this.pack();
        this.setVisible(true);
    }
    public synchronized void startThread(){
        stopped=false;
        thread=new CounterThread();
        thread.start();
    }
    public synchronized void stopThread(){
        stopped=true;
    }
    private static void constructGUI(){
        JFrame.setDefaultLookAndFeelDecorated(true);
        StopThreadDemo frame=new StopThreadDemo(
                "Stop Thread Demo");
    }
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                constructGUI();
            }
        });
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第13张图片

19.7 可见性
1.代码清单19.10 Consistent类

package app19;
public class Consistent{
    static boolean started=false;

    public synchronized static void setStarted(){
        started=true;
    }

    public synchronized static boolean getStarted(){
        return started;
    }

    public static void main(String[] args){
        Thread thread1=new Thread(new Runnable(){
            public void run(){
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                }
                setStarted();
                System.out.println("started set to true");
            }
        });
        thread1.start();
        while(!getStarted()){
            //wait until started
        }
        System.out.println("Wait 3 seconds and exit");
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第14张图片

19.8 线程协调
1.代码清单19.12 DeliveryNoteHolder类

package app19;
public class DeliveryNoteHolder{
    private String deliveryNote;
    private boolean available=false;

    public synchronized String get(){
        while(available==false){
            try{
                wait();
            }catch(InterruptedException e){}
        }
        available=false;
        System.out.println(System.currentTimeMillis()
            +":got"+deliveryNote);
        notifyAll();
        return deliveryNote;
    }
    public synchronized void put(String deliveryNote){
        while(available==true){
            try{
                wait();
            }catch (InterruptedException e){}
        }
        this.deliveryNote=deliveryNote;
        available=true;
        System.out.println(System.currentTimeMillis()+
        ":Put"+deliveryNote);
        notifyAll();
    }
}

2.代码清单19.13 DispatcherThread类

package app19;
public class DispatcherThread extends Thread{
    private DeliveryNoteHolder deliveryNoteHolder;

    String[] deliveryNotes={"XY23.1234 Arnie Rd.",
            "XY24.3330 Quebec St.",
            "XY25.909 Swenson Ave.",
            "XY26.4830 Davidson Blvd.",
            "XY27.9900 Old York Dr."};
    public DispatcherThread(DeliveryNoteHolder holder){
        deliveryNoteHolder=holder;
    }
    public void run(){
        for(int i=0;i

3.代码清单19.14 DriverThread类

package app19;
public class DriverThread extends Thread{
    DeliveryNoteHolder deliveryNoteHolder;
    boolean stopped=false;
    String driverName;

    public DriverThread(DeliveryNoteHolder holder,String
            driverName){
        deliveryNoteHolder=holder;
        this.driverName=driverName;
    }
    public void run(){
        while(!stopped){
            String deliveryNote=deliveryNoteHolder.get();
            try{
                sleep(300);
            }catch(InterruptedException e){
            }
        }
    }
}

4.代码清单19.15 ThreadCoordinationDemo类

package app19;
public class ThreadCoordinationDemo{
    public static void main(String[] args){
        DeliveryNoteHolder c=new DeliveryNoteHolder();
        DispatcherThread dispatcherThread=
            new DispatcherThread(c);
        DriverThread driverThread1=new DriverThread(c,"Eddie");
        dispatcherThread.start();
        driverThread1.start();
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第15张图片

19.9 使用定时器
1.代码清单19.16 使用Timer

package app19;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class TimerDemo extends JFrame{
    String[] questions={"What is the largest mammal?",
    "Who is the current prime minister of Japan?",
    "Who invented the Internet?",
    "What is the smallest country in the world?",
    "What is the biggest city in America?",
    "Finished.Please remain seated"};;

JLabel questionLabel=new JLabel("Click Start to begin");
JTextField answer=new JTextField();
JButton startButton=new JComboBox();
JComboBox answerBox=new JComboBox();
int counter=0;
Timer timer=new Timer();
public TimerDemo(String title){
    super(title);
    init();
}
private void init(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().setLayout(new BorderLayout());
    this.getContentPane().add(questionLabel,BorderLayout.WEST);
    questionLabel.setPreferredSize(new Dimension(300,15));
    answer.setPreferredSize(new Dimension(100,15));
    this.getContentPane().add(answer.BorderLayout.CENTER);
    this.getContentPane().add(startButton,BorderLayout.EAST);
    startButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
             ((JButton) e.getSource()).setEnabled(false);
             timer.schedule(
                 new DisplayQuestionTask(),0,10*1000);
        }
    });
    this.getContentPane().add(answerBox,BorderLayout.SOUTH);
    this.startButton.setFocusable(true);
    this.pack();
    this.setVisible(true);
}
private String getNextQuestion(){
    return questions[counter++];
}
private static void constructGUI(){
    JFrame.setDefaultLookAndFeelDecorated(true);
    TimerDemo frame=new TimerDemo("Timer Demo");
}
public static void main(String[] args){
    javax.swing.SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            constructGUI();
        }
    });
}
class DisplayQuestionTask extends TimerTask{
    public void run(){
    Toolkit.getDefaultToolkit().beep();
    if(counter>0){
        answerBox.addItem(answer.getText());
        answer.setText("");
    }
    String NextQuestion=getNextQuestion();
    questionLabel.setText(nextQuestion);
    if(counter==questions.length){
        timer.cancel();
    }
    }
}
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第16张图片

第20章并发工具
20.2 Executor和ExecutorService
1.代码清单20.2 ImageSearcher类

package app20.imagesearcher;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;

public class ImageSearcher extends JFrame
        implements ActionListener{
    public static final int MAX_RESULT=300;
    JButton searchButton=new JButton("Search");
    DefaultListModel listModel;
    JList imageList;
    Executor executor=Executors.newFixedThreadPool(10);
    AtomicInteger fileCounter=new AtomicInteger(1);

    public ImageSearcher(String title){
        super(title);
        init();
    }
    private void init(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        this.add(searchButton,BorderLayout.NORTH);
        listModel=new DefaultListModel();
        imageList=new JList(listModel);
        this.add(new JScrollPane(imageList),BorderLayout.CENTER);
        this.pack();
        this.setSize(800,650);
        searchButton.addActionListener(this);
        this.setVisible(true);
        //center frame
        this.setLocationRelativeTo(null);
    }
    private static void constructGUI(){
        JFrame.setDefaultLookAndFeelDecorated(true);
        ImageSearcher frame=new ImageSearcher("Image Searcher");
    }
    public void actionPerformed(ActionEvent e){
        Iterableroots=
                FileSystems.getDefault().getRootDirectories();
        for(Path root:roots){
            executor.execute(new ImageSearcherTask(root,executor,
                    listModel,fileCounter));
        }
    }
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                constructGUI();
            }
        });
    }
}

2.代码清单20.3 ImageSearchTask类

package app20.imagesearcher;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.DefaultListModel;
import javax.swing.SwingUtilities;

public class ImageSearcherTask implements Runnable{
    private Path searchDir;
    private Executor executor;
    private DefaultListModel listModel;
    private AtomicInteger fileCounter;

    public  ImageSearcherTask(Path searchDir,Executor executor,DefaultListModel listModel,
                              AtomicInteger fileCounter){
        this.searchDir=searchDir;
        this.executor=executor;
        this.listModel=listModel;
        this.fileCounter=fileCounter;
    }
    @Override
    public void run(){
        if(fileCounter.get()>ImageSearcher.MAX_RESULT){
            return;
        }
        try(DirectoryStreamchildren=
                    Files.newDirectoryStream(searchDir)){
            for(final Path child:children){
                if(Files.isDirectory(child)){
                    executor.execute(new ImageSearcherTask(child,
                            executor,listModel,fileCounter));
                }else if(Files.isRegularFile(child)){
                    String name=child.getFileName()
                            .toString().toLowerCase();
                    if(name.endsWith(".jpg")){
                        final int fileNumber=
                                fileCounter.getAndIncrement();
                        if(fileNumber>ImageSearcher.MAX_RESULT){
                            break;
                        }
                        SwingUtilities.invokeLater(new Runnable(){
                            public void run(){
                                listModel.addElement(fileNumber+
                                        ":"+child);
                            }
                        });
                    }
                }
            }
        }catch(IOException e){
            System.out.println(e.getMessage());
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第17张图片

20.3 Callable和Future
1.代码清单20.4 FileCountTask类

package app20.filecounter;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class FileCountTask implements Callable{
    Path dir;
    long fileCount=0L;
    public FileCountTask(Path dir){
        this.dir=dir;
    }
    private void doCount(Path parent){
        if(Files.notExists(parent)){
            return;
        }
        try(DirectoryStream children=
                    Files.newDirectoryStream(parent)){
            for(Path child:children){
            if(Files.isDirectory(child)){
                doCount(child);
            }else if(Files.isRegularFile(child)){
                fileCount++;
            }
        }
    }catch(IOException e){
        e.printStackTrace();
    }
}
    @Override
    public Long call() throws Exception{
        System.out.println("Start counting"+dir);
        doCount(dir);
        System.out.println("Finished counting"+dir);
        return fileCount;
    }
}

2.代码清单20.5 FileCounter类

package app20.filecounter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class FileCounter{
    public static void main(String[] args){
        Path[] dirs={
                Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e\\ex_02_03"),
                Paths.get("C:\\Users\\yangxiaopang\\Desktop\\py4e")
        };
        ExecutorService executorService=
                Executors.newFixedThreadPool(dirs.length);

        Future[] results=new Future[dirs.length];
        for(int i=0;i

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第18张图片

第21章网络
22.2 超文本传输协议(HTTP)
1.HTTP是允许Web服务器和浏览器之间通过互联网发送和接收数据的协议。它是一种请求和响应协议。HTTP使用可靠的TCP连接,默认是80端口上的TCP。
2.在HTTP中,总是由客户端先建立一个连接并发送一个HTTP请求,从而发起一次事务。Web服务器总是被动地响应客户端,或者对客户端进行一次回调连接。
22.2.1 HTTP请求
包含三个部分:方法——统一资源标识符(URI)——协议/版本;请求头;请求实体。统一资源定位符(URL)实际上是一种类型的URI。
22.2.2 HTTP响应
包含三个部分:协议-状态码-说明;响应头;响应实体。
22.3.1 解析URL
1.代码清单22.1 解析URL

package app22;
import java.net.URL;

public class URLDemo1{
    public static void main(String[] args)throws Exception{
    URL url=new URL(
    "http://www.yahoo.com:80/en/index.html?name=john#first");
    System.out.println("protocol:"+url.getProtocol());
    System.out.println("port:"+url.getPort());
    System.out.println("host:"+url.getHost());
    System.out.println("path:"+url.getPath());
    System.out.println("file:"+url.getFile());
    System.out.println("query:"+url.getQuery());
    System.out.println("ref:"+url.getRef());
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第19张图片

22.4.1 读Web资源
1.代码清单22.3 读取一个Web资源的头部和内容

package app22;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class URLConnectionDemo1{
    public static void main(String[] args){
        try{
            URL url=new URL("http://www.java.com/");
            URLConnection urlConnection=url.openConnection();
            Map>headers=
                    urlConnection.getHeaderFields();
            Set>>entrySet=
                    headers.entrySet();
            for(Map.Entry>entry:entrySet){
                String headerName=entry.getKey();
                System.out.println("Header Name:"+headerName);
                ListheaderValues=entry.getValue();
                for(String value:headerValues){
                    System.out.print("Header value:"+value);
                }
                System.out.println();
                System.out.println();
            }
            InputStream inputStream=
                    urlConnection.getInputStream();
            BufferedReader bufferedReader=new BufferedReader(
                    new InputStreamReader(inputStream));
            String line=bufferedReader.readLine();
            while(line!=null){
                System.out.println(line);
                line=bufferedReader.readLine();
            }
            bufferedReader.close();
        }catch(MalformedURLException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第20张图片

22.5 java.net.Socket
套接字是一个网络连接的端点。
22.7 一个Web服务器应用程序
22.7.1 HttpServer类
1.代码清单22.5 HttpServer类

package app22.app22.webserver;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;


public class HttpServer {

    // shutdown command
    private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

    // the shutdown command received
    private boolean shutdown = false;

    public static void main(String[] args) {
        HttpServer server = new HttpServer();
        server.await();
    }

    public void await() {
        ServerSocket serverSocket = null;
        int port = 8080;
        try {
            serverSocket = new ServerSocket(port, 1, InetAddress
                    .getByName("127.0.0.1"));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        // Loop waiting for a request
        while (!shutdown) {
            Socket socket = null;
            InputStream input = null;
            OutputStream output = null;
            try {
                socket = serverSocket.accept();
                input = socket.getInputStream();
                output = socket.getOutputStream();
                // create Request object and parse
                Request request = new Request(input);
                request.parse();

                // create Response object
                Response response = new Response(output);
                response.setRequest(request);
                response.sendStaticResource();

                // Close the socket
                socket.close();

                // check if the previous URI is a shutdown command
                shutdown =
                        request.getUri().equals(SHUTDOWN_COMMAND);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }
}

22.7.2 Request类
1.代码清单22.7 Request类

package app22.app22.webserver;
import java.io.InputStream;
import java.io.IOException;

public class Request {
    private InputStream input;
    private String uri;

    public Request(InputStream input) {
        this.input = input;
    }

    public void parse() {
        // Read a set of characters from the socket
        StringBuilder request = new StringBuilder(2048);
        int i;
        byte[] buffer = new byte[2048];
        try {
            i = input.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
            i = -1;
        }
        for (int j = 0; j < i; j++) {
            request.append((char) buffer[j]);
        }
        System.out.print(request.toString());
        uri = parseUri(request.toString());
    }

    private String parseUri(String requestString) {
        int index1 = requestString.indexOf(' ');
        int index2;
        if (index1 != -1) {
            index2 = requestString.indexOf(' ', index1 + 1);
            if (index2 > index1) {
                return requestString.substring(index1 + 1, index2);
            }
        }
        return null;
    }

    public String getUri() {
        return uri;
    }
}

22.7.3 Response类
1.代码清单22.10 Response类

package app22.app22.webserver;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/*
 HTTP Response =
 Status-Line (( general-header | response-header | entity-header ) CRLF)
 CRLF
 [ message-body ]
 Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
 */

public class Response {

    private static final int BUFFER_SIZE = 1024;
    Request request;
    OutputStream output;

    public Response(OutputStream output) {
        this.output = output;
    }

    public void setRequest(Request request) {
        this.request = request;
    }

    public void sendStaticResource() throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];
        Path path = Paths.get(System.getProperty("user.dir"),
                "webroot", request.getUri());
        System.out.println("path:" + path);
        if (Files.exists(path)) {
            try (InputStream inputStream =
                         Files.newInputStream(path)) {
                int ch = inputStream.read(bytes, 0, BUFFER_SIZE);
                while (ch != -1) {
                    output.write(bytes, 0, ch);
                    ch = inputStream.read(bytes, 0, BUFFER_SIZE);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // file not found
            String errorMessage = "HTTP/1.1 404 File Not Found\r\n"
                    + "Content-Type: text/html\r\n"
                    + "Content-Length: 23\r\n" + "\r\n"
                    + "

File Not Found

"; output.write(errorMessage.getBytes()); } } }

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第21张图片

教材学习中的问题和解决过程

  • 问题1:对Java网络编程部分的内容概念模糊、体系和框架掌握不清、重点不明确。
  • 问题解决方案1:在网上查找相关资料并学习总结:
    Java的网络编程主要涉及到的内容是Socket编程。简单地说,Socket,套接字,就是两台主机之间逻辑连接的端点。TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket,本质上就是一组接口,是对TCP/IP协议的封装和应用(程序员层面上)。
    Socket编程主要涉及到客户端和服务器端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。
    客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。
    20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第22张图片

(1)HTTPS和HTTP的区别——
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS和HTTP的区别主要为以下四点:1、https协议需要到ca申请证书,一般免费证书很少,需要交费。2、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
(2)HTTP请求的GET方法和POST方法的区别——
GET和POST是HTTP请求的两种方法,主要区别在于GET方法是请求读取由URL所标志的信息,POST是给服务器添加信息。
(3)在浏览器中输入网址到显示出页面的整个过程——
输出包含域名的网址——浏览器向DNS请求解析域名对应的IP地址——域名系统DNS解析出域名对应的IP地址——浏览器与该服务器建立TCP连接——浏览器发送HTTP请求——服务器通过HTTP响应把页面文件发送给浏览器——TCP连接释放——浏览器解释文件,并显示。

  • 问题2:数据库索引是什么?
  • 问题解决方案2:在网上查找相关资料并学习总结:
    创建数据库索引可以大大提高系统的性能:
    (1)通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
    (2)可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
    (3)可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
    (4)在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
    (5)通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
    增加索引也有许多不利的影响:
    (1)创建索引和维护索引要耗费时间,这种时间随着数据 量的增加而增加。
    (2)索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
    (3)当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

代码调试中的问题和解决过程

  • 问题1:对Android Studio不够了解
  • 问题1解决方案:下载和安装Android Studio
    20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第23张图片

  • 问题2:本周课堂头脑风暴用java实现DH密钥交换算法时出现“Unsupported secret key algorithm:AES”错误
  • 问题2解决方案:通过排查,发现是JDK版本的原因,由于JDK8 update 161之后,DH的密钥长度至少为512位,但AES算法密钥不能达到这样的长度,所以导致报错。故打开IDEA的Run-Edit Configurations-在VM options一栏将-Djdk.crypto.KeyAgreement.legacyKDF=true写入即可。

[代码托管]

https://gitee.com/EvelynYang/20189230Week5/tree/master/src

statistics.sh脚本运行结果的截图

20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结_第24张图片

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 1/3 18/38
第三周 500/1000 1/4 38/76
第四周 1000/2000 1/5 20/96
第五周 1000/3000 1/6 25/121

参考资料

  • 《Java和Android开发学习指南(第二版)(Java for Android.2nd)》
  • Java网络编程
  • 数据库基础总结

你可能感兴趣的:(20189230杨 2018-2019-2 《移动平台开发实践》第5周学习总结)