- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 android 中的库连接到终端仿真器,这将连接到串行设备并且应该显示发送/接收的数据。我应该能够通过终端下方的文本框或通过在终端本身中键入并在两种情况下按键盘上的回车来通过连接发送数据。
当我发送数据时,对我的命令的回复返回到库 onDataReceived(int id, byte[] data)
中的方法。每次我取回数据时,它都会自动运行。我可以看到数据到达日志中。
我的问题是,无论何时数据从串行设备返回,屏幕都不会更新,直到我将文本框置于焦点或按下键盘上的回车按钮。我怎样才能在收到任何东西时更新屏幕。我知道它正在接收数据,当我按下文本框或回车按钮时,所有接收到的数据都会显示出来。
这是我收到数据时调用的方法,ByteArrayInputStream
用新数据更新。 appendToEmulator
直接向终端仿真器写入内容。 notifyUpdate
让模拟器知道屏幕已经改变。
public void onDataReceived(int id, byte[] data)
{
String str = new String(data);
Log.d(TAG, "in data received " + str);
((MyBAIsWrapper)bis).renew(data);
mSession.appendToEmulator(data, 0, data.length);
mSession.notifyUpdate();
}
这是我发东西的地方:
mEntry = (EditText) findViewById(R.id.term_entry);
mEntry.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
/* Ignore enter-key-up events. */
if (event != null && event.getAction() == KeyEvent.ACTION_UP) {
return false;
}
/* Don't try to send something if we are not connected yet. */
TermSession session = mSession;
if (mSession == null) {
Log.d(TAG, "null session ");
return true;
}
Log.d(TAG, "in click event ");
Editable e = (Editable) v.getText();
// call original sendData to send data over serial
String data = e.toString() + "\r\n";
Log.d(TAG, "edittext data is " + data);
//overridden sendData
sendData(data.getBytes());
// send data over serial using original sendData() method
mSelectedAdapter.sendData(data.getBytes());
TextKeyListener.clear(e);
return true;
}
});
我该怎么做才能使屏幕实时更新,而不仅仅是根据用户操作进行更新?
编辑:我认为 invalidate() 是我需要的,但它不起作用。我在 emulatorView 上调用它。 emulatorView 显示终端仿真器的屏幕,是库中继承自 View 的类 http://pastebin.com/MNJ0Zf8P
编辑:所以使整个 View 无效没有任何作用,但我注意到当我使 mEmulatorView 无效时,当我解锁它时屏幕会更新。也是更新后的第一次,我可以点击终端本身,它就会更新。进一步的水龙头什么都不做。非常奇怪,所以它显然正在改变行为,但在我调用它时并没有自动执行任何操作。
编辑:为什么处理程序可以工作而调用它却没有?
编辑,我的全部 Activity :
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import slickdevlabs.apps.usb2seriallib.AdapterConnectionListener;
import slickdevlabs.apps.usb2seriallib.SlickUSB2Serial;
import slickdevlabs.apps.usb2seriallib.USB2SerialAdapter;
import slickdevlabs.apps.usb2seriallib.SlickUSB2Serial.BaudRate;
import slickdevlabs.apps.usb2seriallib.SlickUSB2Serial.DataBits;
import slickdevlabs.apps.usb2seriallib.SlickUSB2Serial.ParityOption;
import slickdevlabs.apps.usb2seriallib.SlickUSB2Serial.StopBits;
import slickdevlabs.apps.usb2seriallib.USB2SerialAdapter.DataListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.method.TextKeyListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import jackpal.androidterm.emulatorview.EmulatorView;
import jackpal.androidterm.emulatorview.TermSession;
public class SerialTerminalActivity extends Activity implements
OnClickListener, OnItemSelectedListener, AdapterConnectionListener,
DataListener {
private static final String TAG = "SerialTerminalActivity";
private EditText mEntry;
private EmulatorView mEmulatorView;
private TermSession mSession;
private OutputStream bos;
private InputStream bis;
private InputStream in;
private OutputStream out;
private Spinner mBaudSpinner;
private Spinner mDataSpinner;
private Spinner mParitySpinner;
private Spinner mStopSpinner;
private Spinner mDeviceSpinner;
private Button mConnect;
private ArrayList<String> mDeviceOutputs;
private ArrayList<USB2SerialAdapter> mDeviceAdapters;
private ArrayAdapter<CharSequence> mDeviceSpinnerAdapter;
private USB2SerialAdapter mSelectedAdapter;
private TextView mCurrentSettings;
boolean attached = false;
private Button mUpdateSettings;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_serial_terminal);
mConnect = (Button) findViewById(R.id.deviceConnect);
mConnect.setOnClickListener(this);
mUpdateSettings = (Button) findViewById(R.id.updateSettings);
mUpdateSettings.setOnClickListener(this);
mBaudSpinner = (Spinner) findViewById(R.id.baudSpinner);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mBaudSpinner.setAdapter(adapter);
String[] tempArray = SlickUSB2Serial.BAUD_RATES;
for (int i = 0; i < tempArray.length; i++) {
adapter.add(tempArray[i]);
}
mBaudSpinner.setSelection(SlickUSB2Serial.BaudRate.BAUD_9600.ordinal());
mDataSpinner = (Spinner) findViewById(R.id.dataSpinner);
adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mDataSpinner.setAdapter(adapter);
tempArray = SlickUSB2Serial.DATA_BITS;
for (int i = 0; i < tempArray.length; i++) {
adapter.add(tempArray[i]);
}
mDataSpinner
.setSelection(SlickUSB2Serial.DataBits.DATA_8_BIT.ordinal());
mParitySpinner = (Spinner) findViewById(R.id.paritySpinner);
adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mParitySpinner.setAdapter(adapter);
tempArray = SlickUSB2Serial.PARITY_OPTIONS;
for (int i = 0; i < tempArray.length; i++) {
adapter.add(tempArray[i]);
}
mParitySpinner.setSelection(SlickUSB2Serial.ParityOption.PARITY_NONE
.ordinal());
mStopSpinner = (Spinner) findViewById(R.id.stopSpinner);
adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mStopSpinner.setAdapter(adapter);
tempArray = SlickUSB2Serial.STOP_BITS;
for (int i = 0; i < tempArray.length; i++) {
adapter.add(tempArray[i]);
}
mStopSpinner
.setSelection(SlickUSB2Serial.StopBits.STOP_1_BIT.ordinal());
mDeviceAdapters = new ArrayList<USB2SerialAdapter>();
mDeviceOutputs = new ArrayList<String>();
mDeviceSpinner = (Spinner) findViewById(R.id.deviceSpinner);
mDeviceSpinnerAdapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_spinner_item);
mDeviceSpinnerAdapter
.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mDeviceSpinner.setAdapter(mDeviceSpinnerAdapter);
mDeviceSpinner.setOnItemSelectedListener(this);
mCurrentSettings = (TextView) findViewById(R.id.currentSettings);
SlickUSB2Serial.initialize(this);
/*
* Text entry box at the bottom of the activity. Note that you can also
* send input (whether from a hardware device or soft keyboard) directly
* to the EmulatorView.
*/
mEntry = (EditText) findViewById(R.id.term_entry);
mEntry.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
/* Ignore enter-key-up events. */
if (event != null && event.getAction() == KeyEvent.ACTION_UP) {
return false;
}
/* Don't try to send something if we are not connected yet. */
TermSession session = mSession;
if (mSession == null) {
Log.d(TAG, "null session ");
return true;
}
Log.d(TAG, "in click event ");
Editable e = (Editable) v.getText();
// call original sendData to send data over serial
String data = e.toString() + "\r\n";
Log.d(TAG, "edittext data is " + data);
//doLocalEcho(data.getBytes());
sendData(data.getBytes());
// send data over serial using original sendData() method
mSelectedAdapter.sendData(data.getBytes());
/* Write to the terminal session. */
session.write(e.toString());
//Log.d(TAG, "edittext to string is " + editText.toString());
session.write('\r');
TextKeyListener.clear(e);
return true;
}
});
/*
* Sends the content of the text entry box to the terminal, without
* sending a carriage return afterwards
*/
Button sendButton = (Button) findViewById(R.id.term_entry_send);
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* Don't try to send something if we are not connected yet. */
TermSession session = mSession;
if (mSession == null) {
Log.d(TAG, "mSession == NULLLLLLLLLLLLL ");
return;
}
Editable editText = (Editable) mEntry.getText();
session.write(editText.toString());
Log.d(TAG, "edittext is " + editText.toString());
TextKeyListener.clear(editText);
Log.d(TAG, "send pressed ");
}
});
/**
* EmulatorView setup.
*/
/* emulatorView from xml. */
EmulatorView view = (EmulatorView) findViewById(R.id.emulatorView);
mEmulatorView = view;
/* Let the EmulatorView know the screen's density. */
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
view.setDensity(metrics);
/* Create a TermSession. */
// TermSession session = mSession;
mSession = new TermSession();
//byte[] a=new byte[]{1,1,1};
byte[] a = new byte[]{'h','e', 'l', 'l', 'o'};
byte[] b = new byte[4096];
//bis = new ByteArrayInputStream(a);
bis = new MyBAIsWrapper(b);
bos = new ByteArrayOutputStream();
mSession.write("testTWO");
//bis = new ByteArrayInputStream(b);
mSession.setTermIn(bis);
mSession.setTermOut(bos);
//session.setTermIn(in);
//session.setTermOut(out);
mSession.write("testONE");
/* Attach the TermSession to the EmulatorView. */
mEmulatorView.attachSession(mSession);
//mSession = session;
// mSession.write("abc");
//session.write("test");
try {
bos.write(b);
bos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* TODO Monday: ByteArrayInputStream() can only be used once. The data in it at creation is all that'll ever be in.
* Find a way to update what bis is pointing to without breaking the bind that bis has to the terminal.
* Recover from Saturday's hangover.
*/
/*
* That's all you have to do! The EmulatorView will call the attached
* TermSession's initializeEmulator() automatically, once it can
* calculate the appropriate screen size for the terminal emulator.
*/
}
public void sendData(byte[] data) {
String str = new String(data);
Log.d(TAG, "send data method value is: " + str);
// this should echo what I send to the terminal in the correct format
//bos = new ByteArrayOutputStream(data.length);
mSession.write(data, 0, data.length);
try {
bos.write(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d(TAG, "EXCEPTION in data sent ");
}
// mSession.write(data, 0, data.length);
// mSession.write('\r');
}
public void onDataReceived(int id, byte[] data) {
String str = new String(data);
Log.d(TAG, "in data received " + str);
((MyBAIsWrapper)bis).renew(data);
mSession.appendToEmulator(data, 0, data.length);
mSession.notifyUpdate();
//mEmulatorView.invalidate();
mEmulatorView.postInvalidate();
/* bis = new ByteArrayInputStream(data);
SerialTerminalActivity.this.runOnUiThread(new Runnable() {
public void run() {
serialSession();
}
});*/
//cast added to keep original code structure
//I recommend defining the bis attribute as the MyBAIsWrapper type in this case
// ((MyBAIsWrapper)bis).renew(data);
//mSession.write(data, 0, data.length);
//mSession.write('\r');
}
public void serialSession() {
Log.d(TAG, "in serial session");
mSession.setTermIn(bis);
mSession.setTermOut(bos);
/* Attach the TermSession to the EmulatorView. */
mEmulatorView.attachSession(mSession);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
changeSelectedAdapter(mDeviceAdapters.get(position));
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
public void changeSelectedAdapter(USB2SerialAdapter adapter) {
Toast.makeText(this, "in changeselectedadapter", Toast.LENGTH_SHORT)
.show();
// if(mSelectedAdapter!=null){
// mDeviceOutputs.set(mDeviceSpinnerAdapter.getPosition(mSelectedAdapter.getDeviceId()+""),mReceiveBox.getText().toString());
mSelectedAdapter = adapter;
mBaudSpinner.setSelection(adapter.getBaudRate().ordinal());
mDataSpinner.setSelection(adapter.getDataBit().ordinal());
mParitySpinner.setSelection(adapter.getParityOption().ordinal());
mStopSpinner.setSelection(adapter.getStopBit().ordinal());
updateCurrentSettingsText();
// mReceiveBox.setText(mDeviceOutputs.get(mDeviceSpinner.getSelectedItemPosition()));
Toast.makeText(this,
"Adapter switched toooo: " + adapter.getDeviceId() + "!",
Toast.LENGTH_SHORT).show();
}
@Override
public void onAdapterConnected(USB2SerialAdapter adapter) {
adapter.setDataListener(this);
mDeviceAdapters.add(adapter);
mDeviceOutputs.add("");
mDeviceSpinnerAdapter.add("" + adapter.getDeviceId());
mDeviceSpinner.setSelection(mDeviceSpinnerAdapter.getCount() - 1);
Toast.makeText(this,
"Adapter: " + adapter.getDeviceId() + " Connected!",
Toast.LENGTH_SHORT).show();
// Toast.makeText(this, "Baud: "+adapter.getBaudRate()+" Connected!",
// Toast.LENGTH_SHORT).show();
}
@Override
public void onAdapterConnectionError(int error, String msg) {
// TODO Auto-generated method stub
if (error == AdapterConnectionListener.ERROR_UNKNOWN_IDS) {
final AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(0)
.setTitle("Choose Adapter Type")
.setItems(new String[] { "Prolific", "FTDI" },
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int optionSelected) {
if (optionSelected == 0) {
SlickUSB2Serial
.connectProlific(SerialTerminalActivity.this);
} else {
SlickUSB2Serial
.connectFTDI(SerialTerminalActivity.this);
}
}
}).create();
dialog.show();
return;
}
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
public void onClick(View v) {
if (v == mConnect) {
SlickUSB2Serial.autoConnect(this);
if (mSelectedAdapter == null) {
Toast.makeText(this, "no adapters detected", Toast.LENGTH_SHORT)
.show();
return;
}
}
else if (v == mUpdateSettings) {
if (mSelectedAdapter == null) {
return;
}
mSelectedAdapter.setCommSettings(BaudRate.values()[mBaudSpinner
.getSelectedItemPosition()], DataBits.values()[mDataSpinner
.getSelectedItemPosition()],
ParityOption.values()[mParitySpinner
.getSelectedItemPosition()],
StopBits.values()[mStopSpinner.getSelectedItemPosition()]);
updateCurrentSettingsText();
Toast.makeText(this, "Updated Settings", Toast.LENGTH_SHORT).show();
}
}
private void updateCurrentSettingsText() {
mCurrentSettings.setText("Current Settings Areeee: "
+ mBaudSpinner.getSelectedItem().toString() + ", "
+ mDataSpinner.getSelectedItem().toString() + ", "
+ mParitySpinner.getSelectedItem().toString() + ", "
+ mStopSpinner.getSelectedItem().toString());
}
/* Echoes local input from the emulator back to the emulator screen. */
private void doLocalEcho(byte[] data) {
Log.d(TAG, "echoing " +
Arrays.toString(data) + " back to terminal");
//I added mSession, is it right?
mSession.appendToEmulator(data, 0, data.length);
mSession.notifyUpdate();
}
@Override
protected void onResume() {
super.onResume();
/*
* You should call this to let EmulatorView know that it's visible on
* screen.
*/
mEmulatorView.onResume();
mEntry.requestFocus();
}
@Override
protected void onPause() {
/*
* You should call this to let EmulatorView know that it's no longer
* visible on screen.
*/
mEmulatorView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
/**
* Finish the TermSession when we're destroyed. This will free
* resources, stop I/O threads, and close the I/O streams attached to
* the session.
*
* For the local session, closing the streams will kill the shell; for
* the Telnet session, it closes the network connection.
*/
if (mSession != null) {
mSession.finish();
}
SlickUSB2Serial.cleanup(this);
super.onDestroy();
}
}
最佳答案
当你想更新它时,你需要使 View 失效。在 UI 线程中,使用 invalidate() , 从非 UI 线程使用 postInvalidate() .
关于java - Android 屏幕在没有用户操作的情况下不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13970312/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!