我有一个客户端/服务器应用程序需要能够启动各种线程,生命周期在10秒到24小时之间。我的TCP连接在后台的一个线程中运行,并且运行正常,但我无法弄清楚如何从绑定到TCP线程的处理程序内部启动单个线程。处理程序可以很好地显示服务器发送的测试字符串,但我无法让Java接受我从该处理程序内部启动任何内容。我已经尝试了一个Intend,runOnUIThread和一个标准线程,每个都是单独的,但它一直在抱怨对非静态字段的静态引用。我理解静态变量,但不确定它在这里谈论什么。我在发布的代码中添加了错误消息作为注释。感谢
static Handler TCP_handler = new Handler()
{
@Override
public void handleMessage(Message msg) {
Message.obtain();
Bundle bundle = msg.getData();
switch( msg.what ){
case 1: // this stuff works fine
String aResponse1 = bundle.getString("messageStringL1");
String aResponse2 = bundle.getString("messageStringL2");
if(aResponse1 != null)
textViewLineOne.setText(aResponse1);
if(aResponse2 != null)
textViewLineTwo.setText(aResponse2);
break;
case 2:
// Method 1
// error: “No enclosing instance of the type MainActivity is accessible in scope”
Intent i = new Intent(MainActivity.this, IdleScreen.class);
// if I take out "MainActivity.this" I get the error “static reference to the non-static method”
MainActivity.this.startActivity(i);
// Method 2
// error: Cannot make a static reference to the non-static method runOnUiThread(Runnable) from the type Activity
MainActivity.runOnUiThread(IdleScreen);
// Method 3
// error: “Cannot make a static reference to the non-static field IdleObj.”
// If I make my Idleobj static it compiles but the thread never runs
IdleObj = new IdleScreen();
Thread IdleScreenThead = new Thread();
IdleScreenThead.start();
break;
}
}
};
更新:我删除了静态并在我的TCP类中创建了一个对象,以便该类可以看到位于MainActivity中的处理程序。我现在可以从处理程序启动线程,但是如果没有运行时错误和NullPointerException,我就无法启动Intent; Intent可以通过按钮正常工作。我尝试在MainActivity的onCreate中保存上下文并使用它来代替MainActivity.this,但同样崩溃。我认为我需要Intent工作的原因是,当我启动每个不同的线程时,我可以包含一个新的屏幕(Activity),用户可以使用键盘或从列表中进行某种选择等。我是在这里正确的道路或需要一些新的想法?
//如果从TCP_handler调用,这会给我一个NullPointerException但是如果从按钮调用则可以正常工作。
意图i =新意图(MainActivity.this,IdleScreen.class);
startActivity(ⅰ);
答案 0 :(得分:0)
静态处理程序是一个坏主意,特别是如果您想与用户界面进行交互。 当应用程序进入后台并破坏应用程序的所有活动时,您将做什么?
如果需要生命周期对象,最好的方法是在Application类的子项中创建它并重写方法onCreate(),您可以在其中实例化某个对象并为其扩展上下文类的应用程序提供引用。还为其对象创建getter。
当活动开始时,你可以调用getApplication()方法,然后转换为你的应用程序的类名,并通过getter获取所需的对象。您可以使用这种方式传递对活动的引用。但是,当调用onPause of Activity时,不要忘记通知该对象 - 这意味着活动很快就会被销毁。
还有一项 - 如果您使用自定义,则应在清单中指定应用程序类 申请类。