簡體   English   中英

Java程序在注冊偵聽器后終止

[英]Java program terminates after registering Listeners

互聯網上的大家好!

我的Java代碼有問題,我確定這只是一個初學者的錯誤,但我無法完全理解問題所在。

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;

public class MultiThreadChatClient
{
private static Socket clientSocket = null;
private static PrintStream os = null;
private static boolean closed = false;

private static void start() 
{           
    int portNumber = 2222;
    String host = "localhost";

    System.out.println("Host=" + host + ", port=" + portNumber);

    try
    {
        clientSocket = new Socket(host, portNumber);
        os = new PrintStream(clientSocket.getOutputStream());
        os.println("KeyListener ID: " + new Random().nextInt());
    } 
    catch (UnknownHostException e) 
    {
        System.err.println("Finner ikke hosten " + host);
    }
    catch (IOException e) 
    {
        System.err.println("Error, fant ingen åpen server på " + host);
    }

    if ( clientSocket == null || os == null )
    {
        closed = true;
    }
    Listener.startListener();
}

public void stop()
{
    closed = true;
    os.close();
    try
    {
        clientSocket.close();
    }
    catch (IOException e) 
    {
        e.printStackTrace();
    }
}

public static void send(String msg)
{
    if (!closed)
    {
        os.println(msg);
    }
}

public static void main( String[] args )
{
    start();
}
}

和班級:

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
import org.jnativehook.mouse.NativeMouseWheelEvent;
import org.jnativehook.mouse.NativeMouseWheelListener;

public class Listener implements NativeKeyListener, NativeMouseInputListener, NativeMouseWheelListener
{
public void nativeKeyPressed(NativeKeyEvent e) 
{   
    MultiThreadChatClient.send(NativeKeyEvent.getKeyText(e.getKeyCode()));
}

public void nativeKeyReleased(NativeKeyEvent e) 
{
}

public void nativeKeyTyped(NativeKeyEvent e)
{
}

public void nativeMouseClicked(NativeMouseEvent e) 
{
}

public void nativeMousePressed(NativeMouseEvent e) 
{
}

public void nativeMouseReleased(NativeMouseEvent e) 
{
}

public void nativeMouseMoved(NativeMouseEvent e)
{
}

public void nativeMouseDragged(NativeMouseEvent e) 
{
}

public void nativeMouseWheelMoved(NativeMouseWheelEvent e)
{
}

public static void startListener()
{
    try 
    {
        GlobalScreen.registerNativeHook();
    }
    catch (NativeHookException ex)
    {
        System.err.println("Et problem oppsto.");
        System.err.println(ex.getMessage());

        System.exit(1);
    }
    Listener listener = new Listener();
    GlobalScreen.getInstance().addNativeKeyListener( listener );
    GlobalScreen.getInstance().addNativeMouseListener( listener );
    GlobalScreen.getInstance().addNativeMouseMotionListener( listener );
    GlobalScreen.getInstance().addNativeMouseWheelListener( listener );
}
}

我的問題是,在將偵聽器中注冊了關鍵偵聽器之后,程序立即以代碼“ 0”終止。

它一直起作用,直到我做了一些事情,現在它才在啟動時終止。 我試圖啟動一個線程只是為了使程序保持活動狀態,並且該方法起作用了,但是沒有一個偵聽器起作用。

先感謝您!

更新:

我嘗試了https://code.google.com/p/jnativehook/wiki/examples中的exampleclass,但是事件不再起作用了嗎?

與上述問題相同的問題。 我的類(上面的類)和示例calscal都可以正常工作,但是現在它們都只是在注冊偵聽器后終止(示例類中的main方法)

是我的月食還是這里有什么問題?

如果不運行您的代碼,我的猜測是jvm的“ main”線程啟動了偵聽器,但隨后沒有阻塞,因此退出了“ main”方法。

您的程序運行並結束。 它結束了,完成了並且完成了。 因此它“停止”。

啟動(新)線程將是正確的方法。 但是不要使用線程“使程序保持活動狀態”,而是將其用於有用的事情。 在您的情況下,線程可以打開套接字並在該套接字上偵聽傳入消息(您正在編寫聊天客戶端,對嗎?)。 如果出現消息,則線程將處理它並做出響應。

或者做一個新的線程你的聽眾的-而不是一個方法startListener ,你可以創建一個名為方法startListenerThread

您的程序流將是:

  • 啟動main方法(主線程)
  • 主線程啟動套接字線程
  • 主線程啟動....(無論如何)
  • 主線程等待,直到所有其他線程都完成(它阻塞)

從Windows Vista開始,Microsoft對SetWindowsHookEx()的工作方式進行了未記錄或未記錄在案的更改。 基本上,它們為可使用的掛鈎數設置了上限,並且還為每個回調設置了處理時間限制。 無法修復,檢測或以其他方式解決此新行為。 請讓我知道您如何設法使大量的鈎子運行,以及您使用的是哪個版本的庫。 有關此問題的其他信息,請參見此處

更新:我想回答有關應用程序到達主程序結束后終止方式不一致的原始問題。 在1.2.0 RC1之前,本機線程連接到JVM的方式中存在一些問題,這些問題導致了您在上面描述的問題的一部分。 現在,該本地線程應該作為用戶線程(而不是守護程序線程)作為用戶線程附加,這將防止應用程序在注冊了本地線程后終止。 我相信這是您最初希望從庫中獲得的行為。

我重新啟動計算機后,它又可以工作了。 我的程序無法正常關閉,並作為偵聽器卡在內存中。 似乎該程序只有在內存中有大約8個同一應用程序運行時才起作用。 我不知道這是怎么發生的,但是在修復關機程序之后,一切應該都會恢復正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM