大家早上好,
我遇到过AlertDialog的一些问题。我有一个EditText组件,我想在MainActivity的变量中输入文本。
这是我的代码:
private void showDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
final EditText input = new EditText(MainActivity.this);
builder.setTitle(R.string.title);
builder.setMessage(R.string.enter_comment);
builder.setView(input);
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// name is the variable I want to change. It has been declared as String name; at the beginning of my MainActivity class.
name = input.getText().toString();
showToast(name);
}
});
builder.setNegativeButton(R.string.annuler, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
this.runOnUiThread(new Runnable() {
public void run() {
builder.show();
}
});
// This line makes the app crash. It doesn't print "Null String" as it should.
//showToast(name);
}
private void showToast(String str) {
if (str != null) {
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "Null String", Toast.LENGTH_SHORT).show();
}
}
我希望你能帮助我。 提前谢谢!
编辑 - 添加完整代码(导入除了>太多)
package com.example.ghost.boxmonitor;
public class MainActivity extends Activity {
public final String ACTION_USB_PERMISSION = "com.ghost.boxmonitor.USB_PERMISSION";
Button startButton, clearButton, stopButton;
TextView textView;
UsbManager usbManager;
UsbDevice device;
UsbSerialDevice serialPort;
UsbDeviceConnection connection;
LinkedList<Box> list;
String text,name;
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
@Override
public void onReceivedData(byte[] arg0) {
String data = null;
try {
data = new String(arg0, "UTF-8");
data.concat("/n");
tvAppend(textView, data);
buildString(data);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection.
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) { //Set Serial Connection Parameters.
setUiEnabled(true);
serialPort.setBaudRate(9600);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
tvAppend(textView,"Serial Connection Opened!\n");
} else {
tvAppend(textView,"Port not opened\n");
Log.d("SERIAL", "PORT NOT OPEN");
}
} else {
tvAppend(textView,"Port null\n");
Log.d("SERIAL", "PORT IS NULL");
}
} else {
tvAppend(textView,"Perm not granted\n");
Log.d("SERIAL", "PERM NOT GRANTED");
}
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
onClickStart(startButton);
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
onClickStop(stopButton);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
usbManager = (UsbManager) getSystemService(this.USB_SERVICE);
startButton = (Button) findViewById(R.id.buttonStart);
clearButton = (Button) findViewById(R.id.buttonClear);
stopButton = (Button) findViewById(R.id.buttonStop);
textView = (TextView) findViewById(R.id.textView);
setUiEnabled(false);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(broadcastReceiver, filter);
list = new LinkedList<Box>();
}
public void setUiEnabled(boolean bool) {
startButton.setEnabled(!bool);
stopButton.setEnabled(bool);
textView.setEnabled(bool);
}
public void onClickStart(View view) {
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
tvAppend(textView, "Device VID : "+Integer.toString(deviceVID)+"\n");
if (deviceVID == 10755 || deviceVID == 9025)//Arduino Vendor ID
{
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
tvAppend(textView,"Arduino detected. Waiting for user authorization...\n");
usbManager.requestPermission(device, pi);
keep = false;
} else {
connection = null;
device = null;
tvAppend(textView,"This device is not an Arduino.\n");
}
if (!keep)
break;
}
}
else{
tvAppend(textView,"No USB device detected.\n");
}
}
public void onClickStop(View view) {
setUiEnabled(false);
serialPort.close();
tvAppend(textView, "\nUSB device unplugged.\nSerial Connection Closed !\n");
}
public void onClickClear(View view) {
textView.setText(" ");
showDialog();
}
private void tvAppend(TextView tv, CharSequence text) {
final TextView ftv = tv;
final CharSequence ftext = text;
runOnUiThread(new Runnable() {
@Override
public void run() {
ftv.append(ftext);
}
});
}
public void interpreter(String text){
String table[] = text.split("&");
String def = Integer.toString(list.size() + 1);
if (table.length == 2) {
if (list.isEmpty()) {
//showDialog();
Box b = new Box(table[0], table[1], def);
list.add(b);
//tvAppend(textView2, b.execute());
} else {
boolean isInList = false;
for (Box b : list) {
if (b.getAddr().compareTo(table[0]) == 0) {
isInList = true;
b.setState(table[1]);
//tvAppend(textView2, b.execute());
}
}
if (!isInList) {
//showDialog();
Box b = new Box(table[0], table[1], def);
list.add(b);
//tvAppend(textView2, b.execute());
}
}
}
}
public void buildString(String data){
int len = data.length();
char c;
for (int i = 0; i<len; i++){
c = data.charAt(i);
switch (c){
case '#':
text = "";
break;
case '!':
interpreter(text);
break;
default:
text+=c;
break;
}
}
}
private void showDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
final EditText input = new EditText(MainActivity.this);
builder.setTitle("Title");
builder.setMessage("Message");
builder.setView(input);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
name = input.getText().toString();
Log.d("MyTag", "name in onClick()" + name);
showToast(name);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
showToast(name);
}
private void showToast(String str) {
if (str != null) {
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "Null String", Toast.LENGTH_SHORT).show();
}
}
}
因此,每次我在串行线上接收数据时,我都会构建一个字符串,如果字符串完整,我会调用解释器。如果字符串描述了一个新Box,我调用showDialog方法让用户给它一个名字。
编辑编辑 - 解决方案
请参阅下面的答案以及相关评论。据我所知,你不能在UiThread之外的其他线程中更改UI(现在看来很明显,但是......)。
答案 0 :(得分:0)
name = input.getText().toString();
中的这一行会对name
变量进行分配
用日志检查 - 放
name = input.getText().toString();
Log.d("MyTag", "name in onClick()" + name);
然后在控制台中我看到:
所以它正在工作。解除dialog
后,您可以使用name
变量。
或者请详细说明。
<强> PS。一个提示。如果您在showDialog()
中使用Activity
方法,则无需使用runOnUiThread
技巧。只需致电builder.show();
即可。
好的,这里是Activity
的完整代码,一切正常,包括showDialog()
方法结尾的Toast。
public class MainActivity extends AppCompatActivity {
final String ACTION = "myActionForBroadcast";
String name;
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("MyTag", "onReceive: context" + context.getPackageCodePath());
showDialog();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION);
registerReceiver(broadcastReceiver, filter);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d("MyTag", "Handler run: before send broadcast");
sendBroadcast(new Intent(ACTION));
}
}, 5_000);
}
private void showDialog() {
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
final EditText input = new EditText(MainActivity.this);
builder.setTitle("Title");
builder.setMessage("Message");
builder.setView(input);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("MyTag", "showDialog onClick: name before assign " + name);
name = input.getText().toString();
Log.d("MyTag", "showDialog onClick: name after assign " + name);
showToast(name);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
Log.d("MyTag", "showDialog: before showing dialog");
builder.show();
Log.d("MyTag", "showDialog: before showing toast");
showToast(name);
}
private void showToast(String str) {
if (str != null) {
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "Null String", Toast.LENGTH_SHORT).show();
}
}
}
我改变了Activity
的代码。这是做了什么:
1)我宣布receiver
有一些自定义动作;
2)我在开始后5秒钟模仿onReceive()
;
3)在onReceive()
我刚刚显示了对话框:
4)将日志放在事件上。
我可以为您提出建议 - 在您的onReceive()
中,只需致电showDialog()
并查看是否有效。
如果是 - 那么你的代码就会出错。
!! 另外,如果您在onCreate()中注册接收者,请不要忘记在onDestroy()中取消注册!