Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/210.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从处理程序启动新活动_Android_Multithreading_Android Intent_Android Activity_Handler - Fatal编程技术网

Android 从处理程序启动新活动

Android 从处理程序启动新活动,android,multithreading,android-intent,android-activity,handler,Android,Multithreading,Android Intent,Android Activity,Handler,我有一个客户机/服务器应用程序,需要能够启动不同的活动。我有一个在后台连续运行的工作TCP线程,在我的MainActivity中有一个工作处理程序,TCP线程使用它来发送消息。问题是让处理程序启动字符串以外的任何东西。我的TCP线程在启动时创建MainActivity的对象,这样它就可以访问我的处理程序,因为我的处理程序不是静态的。如果我从MainActivity上的一个按钮运行它,那么一切都可以正常工作,但是当从处理程序启动时,我在所有事情上都会出现NullPointException。我相信

我有一个客户机/服务器应用程序,需要能够启动不同的活动。我有一个在后台连续运行的工作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中的处理程序调用意图。所以我想说这个问题已经解决了-谢谢。