我有一个客户端/服务器应用程序,需要能够启动不同的活动。我有一个工作的TCP线程,它在后台连续运行,我的MainAcitivty中有一个工作处理程序,TCP线程用它来发送消息。问题是让处理程序启动除字符串以外的任何东西。我的TCP线程在启动时创建MainActivity的一个对象,因此它可以访问我必须执行的处理程序,因为我的处理程序不是静态的。如果我从MainActivity上的按钮运行它,一切正常,但是当我从处理程序启动时,我得到了所有内容的nullpointexceptions。我相信它不喜欢我的语境,但我无法找到解决方法。感谢
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
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
// nullpointer exception error
Intent i = new Intent(MainActivity.this, IdleScreen.class);
startActivity(i);
// Method 2
// nullpointer exception error
Toast.makeText(MainContextSaved, "This is Toast!!!", Toast.LENGTH_SHORT).show();
// Method 3
// this launches but can only write to the MainActivty textview
runOnUiThread(IdleScreenUI);
break;
}
}
};
private Runnable IdleScreenUI = new Runnable() {
@Override
public void run() {
// this is the new screen I want to display
setContentView(R.layout.idlescreen ); // nullpointer exception error
// this is a textview in the MainActivity and it works
// textViewLineOne.setText("hello");
// null pointer exception error
Toast.makeText(MainContextSaved, "This is Toast!!!", Toast.LENGTH_SHORT).show();
}
};
答案 0 :(得分:2)
My TCP thread creates an object of the MainActivity on start up.
即使您创建活动的对象,也不是真正的活动上下文。这就是为什么你无法开始其他活动。
如果我正确理解了您的问题,当您尝试从处理程序启动其他活动时,MainActivity位于前台(堆栈中)。
假设您已启动MainActivity,并且您的TCP操作已在后台完成。
如果您的后台TCP操作是从服务完成的,那么当MainActivity启动时,您可以绑定到该服务并将活动上下文共享给服务。
现在使用MainActivity上下文,您可以将Message发送给处理程序。
以下是我创建的示例..
<强> CustomService.java 强>
public class CustomService extends Service {
private final IBinder mIBinder = new LocalBinder();
// temporary handler
private Handler mHandler = new Handler();
// context to hold MainActivity handler
private Context mActivityContext = null;
@Override
public int onStartCommand(Intent intent, int flag, int startId) {
// for testing Iam sending an empty message to the handler after 10 seconds
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (mActivityContext != null) {
((MainActivity) mActivityContext).TCP_handler.sendEmptyMessage(2);
}
}
}, 10000);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return mIBinder;
}
public void setActivityContext(Activity activityContext) {
mActivityContext = activityContext;
}
public class LocalBinder extends Binder {
public CustomService getInstance() {
return CustomService.this;
}
}
}
现在,您可以从活动启动服务并绑定服务连接。
<强> MainActivity.java 强>
public class MainActivity extends ActionBarActivity {
CustomService customService = null;
TextView textViewLineOne;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// start the service, even if already running no problem.
startService(new Intent(this, CustomService.class));
// bind to the service.
bindService(new Intent(this,
CustomService.class), mConnection, Context.BIND_AUTO_CREATE);
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
customService = ((CustomService.LocalBinder) iBinder).getInstance();
// pass the activity context to the service
customService.setActivityContext(MainActivity.this);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
customService = null;
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (customService != null) {
// Detach the service connection.
unbindService(mConnection);
}
}
// Add your handler code stuff here..
}
答案 1 :(得分:1)
Handler类没有startActivity()方法,是吗! 您可以使用静态上下文并在onCreate()中存储活动的值,然后调用context.startActivity()