2013-04-05 92 views
2

我想创建一个处理程序在我的应用程序的开始,所以我可以有两个线程工作1的用户界面和2我的服务器,我这样做,所以服务器将不会阻止用户界面滞后,并有用地排序我的滞后问题,但无论如何,我正在看这个网站http://crodrigues.com/updating-the-ui-from-a-background-thread-on-android/,这个家伙创建一个runnable方法,运行方法,还有一个名为updateGame的方法,它总是在该方法运行时调用,现在我试过了他的代码像这样Android处理程序和线程在开始时没有运行?

public class MainActivity extends Activity { 

private static final String TAG = gameObject.class.getSimpleName(); 
//Create a handler to deal with the server 
private Handler serverHandler = new Handler(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //Turn off title 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    //Make the application full screen 
    getWindow().setFlags(
      WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    setContentView(new gamePanel(this)); 
    Log.d(TAG, "View added"); 

    //Server method 
    new Thread(new Runnable() { onServer(); }).start(); 
} 

final Runnable updateRunnable = new Runnable() { 
    public void run() { 
     //call the activity method that updates the UI 
     updateGame(); 
    } 
}; 

//Give the positions to the game 
public void updateGame() 
{ 
    Log.d(TAG, "Update that game"); 
} 

//Update/run the server 
private void onServer() 
{ 
    if(gamePanel.rtnServerState() == true) 
    { 
     Log.d(TAG, "Start the server"); 
    } 

    serverHandler.post(updateRunnable); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

public void onDestroy() 
{ 
    Log.d(TAG, "Destroying... "); 
    super.onDestroy(); 
} 

public void onStop() 
{ 
    Log.d(TAG, "Stopping... "); 
    super.onStop(); 
} 
} 

和我的updateGame只运行一次。任何人都可以看到为什么它不能在后台运行的问题?

帆布

更新后

public class MainActivity extends Activity { 

private static final String TAG = gameObject.class.getSimpleName(); 
private final Handler serverHandler = new Handler(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //Turn off title 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    //Make the application full screen 
    getWindow().setFlags(
      WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    setContentView(new gamePanel(this)); 

    TextView textView = new TextView(this); 
    textView.setTextSize(40); 
    String message = "hello"; 
    textView.setText(message); 

    Log.d(TAG, "View added"); 
    //Server method 
    new Thread(new Runnable() { 

    @Override 
    public void run() { onServer(); } }).start(); 
} 

private void updateServer() 
{ 
    Log.d(TAG, "testing"); 
} 


//Update/run the server 
private void onServer() 
{ 
    if(gamePanel.rtnServerState() == true) 
    { 
     Log.d(TAG, "Start the server"); 
    } 

    serverHandler.post(updateRunnable); 
} 

//Update/server 
final Runnable updateRunnable = new Runnable() { 
    public boolean running = true; 
    public void run() { 
     while(running){ 
      //call the activity method that updates the UI 
      updateServer(); 
     } 
    } 
}; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

public void onDestroy() 
{ 
    Log.d(TAG, "Destroying... "); 
    super.onDestroy(); 
} 

public void onStop() 
{ 
    Log.d(TAG, "Stopping... "); 
    super.onStop(); 
} 
} 

更新编号2

public class MainActivity extends Activity { 

private static final String TAG = gameObject.class.getSimpleName(); 
private final Handler serverHandler = new Handler(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //Turn off title 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    //Make the application full screen 
    getWindow().setFlags(
      WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    setContentView(new gamePanel(this)); 

    TextView textView = new TextView(this); 
    textView.setTextSize(40); 
    String message = "hello"; 
    textView.setText(message); 

    Log.d(TAG, "View added"); 
    //Server method 
    Runnable server = new Runnable() { 
     public boolean running = true; 
     public void run() { 
      while(running){ 
       onServer(); // Make sure this blocks in some way 
      } 
     } 
    }; 
} 

private void updateServer() 
{ 
    Log.d(TAG, "testing"); 
} 


//Update/run the server 
private void onServer() 
{ 
    if(gamePanel.rtnServerState() == true) 
    { 
     Log.d(TAG, "Start the server"); 
    } 

    serverHandler.post(updateRunnable); 
} 

//Update/server 
final Runnable updateRunnable = new Runnable() { 
    public void run() { 
     //call the activity method that updates the UI 
     updateServer(); 
    } 
}; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 

public void onDestroy() 
{ 
    Log.d(TAG, "Destroying... "); 
    super.onDestroy(); 
} 

public void onStop() 
{ 
    Log.d(TAG, "Stopping... "); 
    super.onStop(); 
} 
} 

回答

2

可运行对象run方法是响应于创建新线程之后才调用一次,拨打您的.start()电话。

通常你做这样的事情:

final Runnable myRunnable = new Runnable() { 
    public boolean running = true; 
    public void run() { 
     while(running){ 
      doSomething(); 
     } 
    } 
}; 

但我不知道这是做到这一点的最好办法。方法将不断地被不必要地调用。

相反,将您的服务器逻辑放在可运行的run()方法中。在那里使用我上面列出的while(running){...}结构,但要确保那里有阻塞呼叫。无论是来自网络套接字,BlockingQueue等。这样它不会不必要地循环。


编辑

从注释中讨论。离开

final Runnable updateRunnable = new Runnable() { 
    public void run() { 
     //call the activity method that updates the UI 
     updateGame(); 
    } 
}; 

,因为它是和更改

new Thread(new Runnable() { onServer(); }).start(); 

Runnable server = new Runnable() { 
    public boolean running = true; 
    public void run() { 
     while(running){ 
      onServer(); // Make sure this blocks in some way 
     } 
    } 
} 
new Thread(server).start(); 
+0

我这样做的工作正常,但现在我的用户界面被冻结,我想要做的是允许UI线程运行,而这个新的线程“工作线程”将处理所有的网络处理,并希望停止我的应用程序主机滞后,导致网络延迟3秒钟。 – Canvas 2013-04-05 19:16:59

+0

我编辑了我的帖子。为什么不只是让“服务器/网络处理器”成为一个线程,并且一旦确定UI应该更新,就调用'serverHandler.post(new Runnable(){updateGame();});' – jedwards 2013-04-05 19:27:15

+0

没有联网,一旦用户按下了主机游戏,他们就成为了服务器,我的updateGame()什么也不做,我试图找出如何为UI启动一个线程并创建一个工作线程。 – Canvas 2013-04-05 19:29:49

0

在教程UI只在按一下按钮更新,但是你在onCreate方法做它只有一次。如果你以@jedwards的方式来做,你的用户界面会在你写的时候冻结。不要一直更新UI。尝试使用timer或使用sockets进行更新。它会更有效,你的UI不会冻结。

定时器例如

import java.util.Timer; 
import java.util.TimerTask; 
... 

TimerTask task = new TimerTask() { 
    @Override 
    public void run() { 
     // update UI 
    } 
}; 
Timer timer = new Timer(); 
// 1000 - after 1 second run this timer 
// 3000 - and do it every 3 second 
timer.schedule(task, 1000, 3000); 

我不会写插座的例子,因为有很多来写。我发现了this教程,您可以在其中阅读有关android套接字编程的内容。

顺便说一句当然,你应该只使用套接字或定时器更新实体数据,而不是整个UI。

+0

任何示例代码? – Canvas 2013-04-05 19:23:25