android中三种onClick事件的实现,与对比
在达内培训,刚接触android不久,对于button的onclick事件有点纠结。因为上了两三天就换了个老师,两个老师讲onclick事件用了两种不同的实现方法,我才发现可以有好几种方式实现。
方式一:在activity的onCreate()方法中,嵌入如下代码:
Button button =(Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
TextView textview = (TextView)findViewById(R.id.textView1);
textview.setText("Button");
}
});
这种方式用findviewbyid通过id实例化出来这个button,然后通过设置button的listener监听对象,并同时实现接口OnClickListenter的OnClick()方法。这种方式的代码量不多,但是在java中,面向对象的思想,关于耦合,模块化它达不到。代码堆叠在一起,比较臃肿。
方式二:让acticity持有TextView,并且新建类Button_Listener实现接口OnClickListener,activity中的代码为:
public class TestOnClickActivity extendsActivity {
private TextView textview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button)findViewById(R.id.button1);
this.textview = (TextView)findViewById(R.id.textView1);
button.setOnClickListener(new Button_Listener(this));
}
public TextView getTextview() {
return this.textview;
}
}
类Button_Listener的代码为:
class Button_Listener implements OnClickListener {
private TestOnClickActivity activity;
public Button_Listener(TestOnClickActivity activity) {
this.activity = activity;
}
@Override
public void onClick(View v) {
TextView textview = activity.getTextview();
textview.setText("你点击了Button");
}
}
方式二:
在方式二中,为了改正方式一的接口实现的不规范,特别重新建立了一个类:Button_Listener。
这种方式代码结构清晰,在为Button加入监听方法是,只需要newButton_Listener(this)即可。但同时,我们也能够发现,因为不属于类TestOnClickActivity,所以类Button_Listener必须通过持有TestOnClickActivity,将其作为成员。并且,我们需要在TestOnClickActivity中显示的加入TextView,并书写getTextview()方法,才能够实现我们的程序意图。
虽然代码的模块化,解耦化得到了一定程度上的实现,但换来的结果是代码更多,书写更加繁琐。
方式三:在组件文件main.xml中,对Button加入:
android:onClick="onClick_Event"
在activity中加入以下代码:
public void onClick_Event(View view){
TextView textview = (TextView)findViewById(R.id.textView1);
textview.setText("Button");
}
在方式三种,我们只需要在TestOnClickActivity中增加一个成员函数onClick_Event(),并在组件文件中加入对其的使用描述即可。
代码结构简单,清晰,代码量也大大减少,并且通过xml文件的可配置性,增长了工程的可维护性,模块化进一步增强!
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
简介
Java中Socket通信简介
单线程一对一服务器1——>1客户端单线程一对一服务器1<——>1客户端
多线程一对多服务器1<——>N客户端【非聊天室的服务器通过用户输入发送数据】
多线程一对多服务器1<——>N客户端【聊天室】
多线程最终服务器和客户端集成一体【swing程序】


二:::::
- package com17;
- import java.io.IOException;
- import java.io.PrintStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- public class Server {
- public static void main(String[] args) {
- //创建月hi个ServerSocket,用于监听客户端Socket的连接请求
- try {
- ServerSocket ss=new ServerSocket(30000);
- //采用死循环不断接受来自客户端的请求
- while(true)
- {
- //每当接受到客户端socket的请求,服务端也对应产生一个socket
- Socket s=ss.accept();
- System.out.println("IP为"+s.getInetAddress()+"连接此服务器");
- //将Socket对应的输出流包装成PrintStream
- PrintStream ps=new PrintStream(s.getOutputStream());
- //进行普通的io操作
- ps.println("客户端您好,我是服务器。");
- ps.close();
- s.close();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
客户端:
- package com17;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.Socket;
- public class Client {
- public static void main(String[] args) {
- try
- {
- Socket socket=new Socket("127.0.0.1",30000);
- //将socket对应的输入流包装成BufferedReader
- BufferedReader br=new BufferedReader( new InputStreamReader(socket.getInputStream()));
- //进行普通的io操作
- String line=br.readLine();
- System.out.println("来自服务器的数据::"+line);
- br.close();
- socket.close();
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- }
效果如下:


- while( true)
- //每当接受到客户端socket的请求,服务端也对应产生一个socket
- Socket s=ss.accept();
- System. out.println( "IP为"+s.getInetAddress()+ "连接此服务器" );
- //接受客户端发送的数据
- BufferedReader br= new BufferedReader( new InputStreamReader(s.getInputStream()));
- System. out.println( "来自客户端的数据:" +br.readLine());
- //将Socket对应的输出流包装成PrintStream
- PrintStream ps= new PrintStream(s.getOutputStream());
- //进行普通的 io操作
- ps.println( "客户端您好,我是服务器。" );
- ps.close();
- br.close();
- s.close();
客户端:
- try
- {
- Socket socket=new Socket("127.0.0.1",30000);
- //发送数据
- PrintStream ps= new PrintStream(socket.getOutputStream());
- ps.println( "您好,我是客户端" );
- //将socket对应的输入流包装成BufferedReader
- BufferedReader br= new BufferedReader( new InputStreamReader(socket.getInputStream()));
- //进行普通的io操作
- String line=br.readLine();
- System. out.println( "来自服务器的数据::" +line);
- br.close();
- ps.close();
- socket.close();
- }

- //获取该socket对应的输出流
- PrintStream ps= new PrintStream(s.getOutputStream());
- String line= null;
- //不断读取键盘的输入
- BufferedReader br= new BufferedReader( new InputStreamReader(System.in));
- while((line=br.readLine())!= null)
- {
- //将用户的键盘输入内容写入socket对应的输出流
- ps.println(line);
- }
三:::::


- package com17.tcp;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- public class MyServer {
- public static void main(String[] args) {
- try {
- ServerSocket ss=new ServerSocket(30000);
- while(true)
- {
- //此行代码会阻塞,将一直等待别人的连接
- Socket s=ss.accept();
- if(s.isConnected())
- {
- System.out.println("一个客户端连接此服务器"+s.getInetAddress());
- }
- //每当客户端连接后启动一条ServerThread线程为该客户端服务
- new Thread( new ServerThread(s)).start();
- //发送数据到客户端
- new Thread(new ServerThread2(s)).start();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- package com17.tcp;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintStream;
- import java.net.Socket;
- import java.util.Scanner;
- public class ServerThread implements Runnable {
- //定义当前线程所处理的socket
- Socket s=null;
- //该线程所处理的socket所对应的输入流
- BufferedReader br=null;
- public ServerThread(Socket s)
- {
- try
- {
- this.s=s;
- //初始化socket对应的输入流
- br=new BufferedReader(new InputStreamReader(s.getInputStream()));
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- @Override
- public void run() {
- try
- {
- String content=null;
- //采用循环不断从Socket中读取客户端发送过来的数据
- while((content=readFromClient())!=null)
- {
- System.out.println("来自客户端消息:"+content);
- }
- System.out.println("消息:"+content);
- PrintStream ps=new PrintStream(s.getOutputStream());
- ps.println(br.readLine());
- }catch(Exception e)
- {
- try
- {
- s.close();
- }catch(IOException ex)
- {
- ex.printStackTrace();
- }
- }
- }
- //定义读取客户端数据的方法
- private String readFromClient()
- {
- try
- {
- return br.readLine();
- }
- //如果捕捉到异常,表明该socket对应的客户端已经关闭
- catch(IOException e)
- {
- e.printStackTrace();
- }
- return null;
- }
- }
- package com17.tcp;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintStream;
- import java.net.Socket;
- public class ServerThread2 implements Runnable {
- private Socket s;
- //用来处理发送数据的
- private PrintStream ps=null;
- public ServerThread2(Socket s)
- {
- try
- {
- this.s=s;
- ps=new PrintStream(s.getOutputStream());
- }
- catch(IOException e)
- {
- try
- {
- s.close();
- }
- catch(IOException ex)
- {
- ex.printStackTrace();
- }
- }
- }
- @Override
- public void run() {
- try
- {
- //发送数据到客户端
- String line=null;
- //不断读取键盘的输入
- BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
- while((line=br.readLine())!=null)
- {
- //将用户的键盘输入内容写入socket对应的输出流
- ps.println(line);
- }
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- }
- package com17.tcp;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintStream;
- import java.net.Socket;
- //负责读取用户的键盘输入,并将用户输入的数据写入socket对应的输出流中
- //一条负责读取socket对应输入流中的数据(从服务器发送过来的数据)
- //并将这些数据打印输出。其中负责读取用户键盘输入的线程由MyClient负责,也就是由程序的主线程负责。
- public class MyClient {
- public static void main(String[] args) {
- try
- {
- Socket s=new Socket("127.0.0.1",30000);
- //客户端启动clientThread县城不断读取来自服务器的数据
- new Thread(new ClientThread(s)).start();
- //获取该socket对应的输出流
- PrintStream ps=new PrintStream(s.getOutputStream());
- String line=null;
- //不断读取键盘的输入
- BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
- while((line=br.readLine())!=null)
- {
- //将用户的键盘输入内容写入socket对应的输出流
- ps.println(line);
- }
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- }
- package com17.tcp;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.Socket;
- public class ClientThread implements Runnable {
- //该线程负责处理的socket
- private Socket s;
- //该线程所处理的socket所对应的输入流
- BufferedReader br=null;
- public ClientThread(Socket s) throws IOException
- {
- this.s=s;
- br=new BufferedReader(new InputStreamReader(s.getInputStream()));
- }
- @Override
- public void run() {
- try
- {
- String content=null;
- //不断读取socket输入流中的内容,讲这些内容打印输出
- while((content=br.readLine())!=null)
- {
- System.out.println("来自服务器端消息:"+content);
- }
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- }




- //采用循环不断从Socket中读取客户端发送过来的数据
- while((content=readFromClient ())!=null )
- {
- System. out.println( "来自客户端消息:" +content);
- ps.println( "客户端"+s.getInetAddress()+"消息已经收入到,消息为:" +content);
- }


- //采用循环不断从Socket中读取客户端发送过来的数据
- while((content=readFromClient())!= null)
- {
- //便利socketList中的每一个socket
- //将读到的内容向每个socket发送一次
- for(Socket s:MyServer. socketList)
- {
- PrintStream ps= new PrintStream(s.getOutputStream());
- ps.println(content);
- }
- }
- ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
- 多线程最终服务器和客户端集成一体【swing程序】
我们通过窗体形式来实验这个socket通信。窗体形式,其实把服务器和客户端集成在一起。因此每个窗体程序既是客户端又是服务器端。窗体应用程序思路:运行窗体后,此服务器在后台默默监听,而前端展示给客户的是我们所谓的客户端。若服务器接受到相应的消息,则反应在客户端窗体消息窗口中。首先脑海中窗体形式如下:
为CS新手补习点图形化知识:
Java中使用Awt和Swing类来完成图形化界面。其中Awt是abstract window tookit(抽象窗口工具库),他是最早的gui库。那为什么会出现swing类呢?他们两者的关联是什么呢?1.Awt在所有平台上展示的界面很丑陋,功能也有限。2.Awt是非常笨拙、非面向对象的编程方式。3.Awt是调用底层平台的GUI实现,因此限制了Awt支持的GUI的实现。而swing则:1.开发的图形界面要不awt优秀。2.采用mvc架构设计,使显示数据与数据来源隔离。3.是纯java开发,所以在任何平台都展示一样的效果,而不是依赖平台。他们之间的关联是:swing是在awt的基础上开发出来,现在很少使用awt组件,大部分使用swing组件。在AWT组件结构:容器的继承关系如下:事件关系如下:还有就是布局管理器组件了。代码中会有相应的解释。而swing组件关系:分析我们脑海中的窗体,差不多我们都知道布局。因为是Tcp协议测试,所以是基于面向链接发送数据。所以在发送之前,首先要连接服务器,若连接上,然后再发送数据。客户端与服务器消息交流都是在中间的消息框中展示。在这个窗体中,到底如何布局呢?这就需要awt的布局管理器。在代码中,我们用的是BorderLayout组件,布局方式是分为东南西北中,若不指定方向,则默认是中间。BoderLayout效果如下:在构造器启动服务,服务一直在监听客户端。若监听到,则开启接受信息的线程,其中线程类作为此主线程类的内部类。代码如下:并且其中有详细的注释:
- package com.test;
- import java.awt.BorderLayout;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.PrintStream;
- import java.net.InetAddress;
- import java.net.ServerSocket;
- import java.net.Socket;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JOptionPane;
- import javax.swing.JPanel;
- import javax.swing.JScrollBar;
- import javax.swing.JScrollPane;
- import javax.swing.JTextArea;
- import javax.swing.JTextField;
- public class SocketTcpDemo1 extends JFrame implements ActionListener {
- //输入的IP标签
- private JLabel ipLable;
- //输入对方的ip地址
- private JTextField sendIp;
- //连接按钮
- private JButton linkBtn;
- //发送的数据框
- private JTextField sendText;
- //显示数据显示框
- private JTextArea showMessage;
- //创建滚动条 主要是创建垂直滚动条
- private JScrollBar verscrollbar;
- //默认端口号
- private int port=30000;
- //发送按钮
- private JButton sendBtn;
- //默认发送的ip
- public String defaultSendIp="127.0.0.1";
- //连接socket
- private Socket socket;
- //构造方法
- public SocketTcpDemo1()
- {
- this.setTitle("测试tcp通信的窗体");
- this.setBounds(200, 200, 500, 500);
- this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- this.setLayout(new BorderLayout());
- //定义消息显示数据框
- showMessage=new JTextArea();
- //设置不可以编辑,消息显示的数据框
- showMessage.setEditable(false);
- //消息显示数据框不够,需要添加滚动条
- JScrollPane messageScrollPane=new JScrollPane(showMessage);
- verscrollbar=messageScrollPane.createVerticalScrollBar();
- //把滚动面板放在JFrame容器中
- this.add(messageScrollPane, BorderLayout.CENTER);
- //设置连接ip的数据框
- JPanel panel=new JPanel(new BorderLayout(5,2));
- //设置发送默认的ip
- sendIp=new JTextField(defaultSendIp);
- panel.add(sendIp,BorderLayout.CENTER);
- //连接按钮
- linkBtn=new JButton("连接");
- panel.add(linkBtn,BorderLayout.EAST);
- //ip标签显示
- ipLable =new JLabel("对方IP:");
- panel.add(ipLable,BorderLayout.WEST);
- //然后把这个panel放在Frame的上方
- this.add(panel,BorderLayout.NORTH);
- //设置发送数据框的位置
- JPanel sendDataPanel=new JPanel(new BorderLayout(5,2));
- //发送数据文本框
- sendText=new JTextField();
- sendDataPanel.add(sendText,BorderLayout.CENTER);
- //发送按钮
- sendBtn=new JButton("发送");
- sendDataPanel.add(sendBtn,BorderLayout.EAST);
- //然后把这个panel放在Frame的下方
- this.add(sendDataPanel,BorderLayout.SOUTH);
- //可视化
- this.setVisible(true);
- //添加事件源
- linkBtn.addActionListener(this);
- sendBtn.addActionListener(this);
- //启动监听服务方法
- TcpServer();
- }
- public void actionPerformed(ActionEvent e) {
- if(linkBtn==e.getSource())
- {
- //判断是否能连接上
- try {
- socket=new Socket(sendIp.getText().trim(),port);
- JOptionPane.showMessageDialog(this, "连接成功");
- } catch (Exception e1) {
- try {
- JOptionPane.showMessageDialog(this, "连接失败");
- socket.close();
- } catch (IOException e2) {
- // TODO Auto-generated catch block
- e2.printStackTrace();
- }
- }
- }
- else if(sendBtn==e.getSource())
- {
- try {
- PrintStream ps=new PrintStream(socket.getOutputStream());
- ps.println(sendText.getText());
- //显示框中显示
- showMessage.append(InetAddress.getLocalHost().getHostAddress()+"说:"+sendText.getText()+"\n");
- sendText.setText("");
- } catch (IOException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- }
- }
- public static void main(String[] args) {
- SocketTcpDemo1 tcpSocket=new SocketTcpDemo1();
- }
- //服务监听
- private void TcpServer()
- {
- try {
- ServerSocket ss = new ServerSocket(port);
- while(true)
- {
- //此行代码会阻塞,将一直等待别人的连接
- Socket s=ss.accept();
- new Thread(new ServerThread(s)).start();
- }
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- class ServerThread implements Runnable {
- //定义当前线程所处理的socket
- Socket s=null;
- //该线程所处理的socket所对应的输入流
- BufferedReader br=null;
- public ServerThread(Socket s)
- {
- try
- {
- this.s=s;
- //初始化socket对应的输入流
- br=new BufferedReader(new InputStreamReader(s.getInputStream()));
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- @Override
- public void run()
- {
- try {
- String content = null;
- while((content = br.readLine()) != null) {
- //服务器发送的消息
- showMessage.append(sendIp.getText().trim()+"说:" + content + "\n");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
效果如下:测试连接窗体:互相通信窗口:至此,目录中的总结都已经整理完毕。整理这部分内容的原因:第一:socket通信,当时元旦两天测试出来,可当时遇到点问题,所以索性把练习之旅记录下来。第二:练习基础中的多线程,多线程这部分,基本上理论都可以讲出来,但是项目中一直没有用到。第三:初次接触图形化界面,因为这方面内容没有涉及到,大部分是在研究web方向,但是就像揭开他的神秘面纱。呵呵,基于以上原因,才有了此次总结的想法。最近一直在研究其他的东西,所以博客没有及时贴出来。(*^__^*)嘻嘻