Android JNI方法签名规则

JNI中对Java方法的签名格式为:(参数)返回值类型 其中参数部分的编码如下:

I : Integer
B : Byte
S : Short
C : Char
V : Void
LJava_Class; : Java中非基本类型
... ...

一个例子:

(LJava/lang/String;I)V

上面的方法签名表示该方法接受String和Integer两个参数,返回Void。

Java语言中对象的部分序列化

public class TestExternalizable implements Externalizable {

	//只对下面2个变量序列化
	int No;
	String name;
	
	//下面的变量没有被序列化
	int age = 0;

	public TestExternalizable() {
		// 在恢复Externalizable对象的时候,默认构造函数会被调用,这一点跟恢复一个Serializable对象不同
		System.out.println("Default Constructor");
	}

	public TestExternalizable(int No, String name, int age) {

		System.out.println("Other Constructor");
		this.name = name;
		this.No = No;
		this.age = age;
	}

	@Override
	public String toString() {
		return "No: " + No + ", Name: " + name + ", age: " + age;
	}

	//序列化数据时调用的函数
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeInt(No);
		out.writeObject(name);
	}

	//恢复数据时调用的函数。需要保证恢复的数据跟序列化时一致
	@Override
	public void readExternal(ObjectInput in) throws IOException,
			ClassNotFoundException {

		No = in.readInt();
		name = (String) in.readObject();
	}

	public static void main(String[] args) {

		TestExternalizable te = new TestExternalizable(10, "lnmcc", 18);
		System.out.println(te.toString());

		try {
			//将一个Externalizable对象保存到一个文件
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("out.dat"));
			out.writeObject(te);
			//刷新并关闭流
			out.close();

			//从文件恢复一个Externalizable对象
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("out.dat"));
			te = (TestExternalizable) in.readObject();
			System.out.println(te.toString());
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

输出:

Other Constructor
No: 10, Name: lnmcc, age: 18
Default Constructor
No: 10, Name: lnmcc, age: 0

结果显示:

  1. 反序列化一个Externalizable对象的时候会调用类的默认构造函数。
  2. No和Name字段成功恢复,age字段由于没有被序列化,为默认值。

Java基本IO操作

public class IODemo {

	public static void main(String[] args) {
		try {
			// 1a.Reading input by lines
			BufferedReader in = new BufferedReader(new FileReader(args[0]));
			String s, s2 = new String();
			while ((s = in.readLine()) != null) {
				s2 += s + "\n";
			}
			in.close();

			// 1b.Reading standard input
			BufferedReader stdin = new BufferedReader(new InputStreamReader(
					System.in));
			System.out.println("Enter a line: ");
			System.out.println(stdin.readLine());

			// 2.Input from memory
			StringReader in2 = new StringReader(s2);
			int c;
			while ((c = in2.read()) != -1) {
				System.out.print((char) c);
			}

			// 3. Formatted memory input
			try {
				DataInputStream in3 = new DataInputStream(
						new StringBufferInputStream(s2));
				while (true) {
					System.out.print((char) in3.readByte());
				}
			} catch (EOFException e) {
				System.out.println("End of stream");
			}

			// 4. Line number reading & file output
			try {
				LineNumberReader li = new LineNumberReader(new StringReader(s2));
				BufferedReader in4 = new BufferedReader(li);
				PrintWriter out1 = new PrintWriter(new BufferedWriter(
						new FileWriter("IODemo.out")));
				while ((s = in4.readLine()) != null) {
					out1.println("Line " + li.getLineNumber() + " " + s);
				}
				out1.close();

			} catch (EOFException e) {
				System.out.println("End of stream");
			}

			// 5. Storing & recovering data
			try {
				DataOutputStream out2 = new DataOutputStream(
						new BufferedOutputStream(new FileOutputStream(
								"Data.txt")));
				out2.writeDouble(3.1415926);
				out2.writeBytes("It is a pi");
				out2.close();

				DataInputStream in5 = new DataInputStream(
						new BufferedInputStream(new FileInputStream("Data.txt")));
				BufferedReader in5br = new BufferedReader(
						new InputStreamReader(in5));
				System.out.println(in5.readDouble());
				System.out.println(in5br.readLine());
			} catch (EOFException e) {
				System.out.println("End of stream");
			}

		} catch (FileNotFoundException e) {
			System.out.println("File Not Found: " + args[1]);
		} catch (IOException e) {
			System.out.println("IO Exception");
		}
	}
}

kindle paperwhite 白屏处理

​ 在使用kpw阅读书籍时,如果碰到书籍中有错误,会出现死机、白屏现象。这种情况没有必要进行刷机这么复杂的处理。正确的处理方式如下:

长按电源键20秒以上,然后等待系统自动重启。重启成功后,删除出现问题的书籍即可。

Java 构建类型安全的枚举类型

在《Java编程思想-网络版》一书中看到一段有意思的代码。

先来看一段Java实现C/C++枚举效果的非类型安全的版本:

public interface Months {
    int JANUARY = 1, 
        FEBRUARY = 2,
        MARCH = 3,
        APRIL = 4,
        ... ...;
}

上面的代码实际上是在利用Java中interface的成员变量会自动成为public static final的事实,这样我们可以使用Months.JANUARY的方法来引用这些值。但是这个方法的缺陷是非类型安全的,因为我们最终获得的其实是个int。这种方法带来的好处只是减少了硬编码。

接下来看看Bruce Eckel提供的类型安全的版本:

public final class Month2 {
    private String name;

    private Month2(String nm) { 
        name = nm; 
    }

    public String toString() {
        return name; 
    }

    public final static Month2
        JAN = new Month2("January"),
        FEB = new Month2("February"),
        MAR = new Month2("March"),
        APR = new Month2("April"),
        MAY = new Month2("May"),
        JUN = new Month2("June"),
        JUL = new Month2("July"),
        AUG = new Month2("August"),
        SEP = new Month2("September"),
        OCT = new Month2("October"),
        NOV = new Month2("November"),
        DEC = new Month2("December");

    public final static Month2[] month = {
        //这里使用2个JAN是为了填充0号位置,这样数组下标可以跟月份一一对应
        JAN, JAN, FEB, MAR, APR, MAY,
        JUN, JUL, AUG, SEP, OCT, NOV,
        DEC
    }; 
    
    public static void main(String[] args) {
        Month2 m = Month2.JAN;
        System.out.println(m);
        m = Month2.month[12];
        System.out.println(m);
        System.out.println(m == Month2.DEC);
        System.out.println(m.equals(Month2.DEC));
    }
}	

ref: 《Java编程思想-网络版》