Android 从处理程序启动新活动
我有一个客户机/服务器应用程序,需要能够启动不同的活动。我有一个在后台连续运行的工作TCP线程,在我的MainActivity中有一个工作处理程序,TCP线程使用它来发送消息。问题是让处理程序启动字符串以外的任何东西。我的TCP线程在启动时创建MainActivity的对象,这样它就可以访问我的处理程序,因为我的处理程序不是静态的。如果我从MainActivity上的一个按钮运行它,那么一切都可以正常工作,但是当从处理程序启动时,我在所有事情上都会出现NullPointException。我相信它不喜欢我的环境,但我找不到合适的工作。谢谢Android 从处理程序启动新活动,android,multithreading,android-intent,android-activity,handler,Android,Multithreading,Android Intent,Android Activity,Handler,我有一个客户机/服务器应用程序,需要能够启动不同的活动。我有一个在后台连续运行的工作TCP线程,在我的MainActivity中有一个工作处理程序,TCP线程使用它来发送消息。问题是让处理程序启动字符串以外的任何东西。我的TCP线程在启动时创建MainActivity的对象,这样它就可以访问我的处理程序,因为我的处理程序不是静态的。如果我从MainActivity上的一个按钮运行它,那么一切都可以正常工作,但是当从处理程序启动时,我在所有事情上都会出现NullPointException。我相信
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();
}
};
处理程序类没有startActivity()方法,是吗! 您可以使用静态上下文并将其中活动的值存储在onCreate()中,然后调用context.startActivity() 即使创建了活动的对象,也不是真正的活动上下文。这就是你无法开始其他活动的原因 如果我正确理解了您的问题,那么当您尝试从处理程序启动其他活动时,MainActivity位于前台(堆栈中) 假设您已启动MainActivity,并且TCP操作在后台完成 如果后台TCP操作是从服务完成的,那么当MainActivity启动时,您可以绑定到该服务并将活动上下文共享到该服务 现在,通过MainActivity上下文,您可以向处理程序发送消息 这是我创建的一个示例 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;
}
}
}
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..
}
现在,您可以从活动启动服务并绑定服务连接
MainActivity.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;
}
}
}
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..
}
好主意,我现在可以直接从处理程序或runOnUiThread启动我的意图,但我不确定如何将两者结合起来。我希望运行runOnUiThread并提供一种方法来更新各种事件的显示,然后在完成后关闭并返回MainActivity。如何启动MainActivity?我只调用setContentView(R.layout.activity_main);来自onCreate。然后我启动我的TCP线程,该线程侦听并连接到服务器。我还有另一个线程,我将使用它来处理我将随时间添加的其他内容。好的。看看我的答案。让我知道它是否有助于我用你的代码创建一个新项目(别忘了将服务添加到你的清单文件中),但我不认为通过专用线程为我的网络数据使用服务有什么好处。我喜欢您将上下文传递给服务/线程并将其转换为main活动的想法。我将其添加到我的项目中,现在可以从MainActivity中的处理程序调用意图。所以我想说这个问题已经解决了-谢谢。