Android:处理来自非 UI 线程的 onTouch 事件
Android: Handling onTouch events from non UI thread
我不确定我正在尝试做的事情是否有意义,但我会试一试:
我的 phone 用作客户端,我需要将有关运动事件的数据发送到服务器。
我正在处理与 AsyncTask 的通信,所以我想在我的 AsyncTask class 中实现 onTouch 方法。
我让我的 AsyncTask 实现了 View.OnTouchListener 但事件并没有真正到达我的 AsyncTask 中的 onTouch 方法。
我猜我遗漏了一些非常基本的东西..
这是 AsyncTask 代码:
public class tpAsyncTask extends AsyncTask<String,String,String> implements View.OnTouchListener {
Context context;
boolean isCancelled = false;
float prevX;
float prevY;
Socket socket;
ObjectOutputStream oos;
private final static String TAG = "ME ASYNCTASK LOGGER: ";
public tpAsyncTask(Context context){
this.context = context;
}
@Override
protected String doInBackground(String... strings) {
String IP = strings[0];
String port = strings[1];
try {
InetAddress inetAddress = InetAddress.getByName(IP);
socket = new Socket(inetAddress,Integer.parseInt(port));
OutputStream os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
while(!isCancelled()) {
Thread.sleep(1000);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
try {
oos.flush();
oos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// PROBLEM IS THAT THE APP NEVER REACH HERE
if(!isCancelled()) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_MOVE:
{
Log.d(TAG, "ACTION MOVE IS PREFORMED");
}
case MotionEvent.ACTION_DOWN:
{
Log.d(TAG, "ACTION DOWN IS PREFORMED");
}
}
}
return false;
}}
谢谢
编辑,解决:
正如此处评论的许多人所说,我必须将我的 onTouch 实现附加到特定视图。
因此,由于我需要我的 onTouch 事件来包含所有屏幕尺寸,我只是创建了一个我的相对布局的对象并将其传递给我的 asyncTask(实现 OnTouchListener)的构造函数,并在我设置的构造函数上 myRelativeLayout.setOnTouchListerner(this)
.
成功了——asyncTask 中的 onTouch 方法现在在我触摸屏幕时被调用。
非常感谢大家。
有点缺乏信息。您是否使用
将 asyncTask 正确地放置在 onTouchListener 视图中
view.setOnTouchListener(yourAsyncTask);
请注意,您的 AsyncTask 对象必须是 运行 对象(而不是新实例或匿名实例)。因此,我建议您在启动 运行 您的 asyncTask 时添加侦听器。
如果您已经这样做了,我建议您 post 更多信息(您的 activity 代码、asyncTask 启动和 setOnTouchListener 部分)。
编辑:
代码示例:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View viewToTouchWithReact=findViewById(R.id.yourViewId);
AsyncTask task=/**.AsynTask creation and launch.**/
viewToTouchWithReact.setOnTouchListener(task);
}
做那样的事情。如果没有启动 asyncTask 的代码和 activity 代码,我不能更精确。抱歉
无法访问代码,因为 AsyncTask 不是用户可以 'touched' 的 UI 元素。您应该将侦听器添加到视图,然后启动异步任务:
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_MOVE:
{
tpAsyncTask<String,String,String> task = new tpAsyncTask<>();
task.execute(motionEvent);
Log.d(TAG, "ACTION MOVE IS PREFORMED");
}
case MotionEvent.ACTION_DOWN:
{
Log.d(TAG, "ACTION DOWN IS PREFORMED");
}
}
return false;
}
});
我认为你的客体关系有点由内而外。与其让你的 AsyncTask
拥有或成为 OnTouchListener
,不如让你的 OnTouchListener
(它总是在 UI 线程中调用)触发 AsyncTask
。
如果您的 AsyncTask
在完成后更新了 UI,那么您将需要跟踪 运行 AsyncTask
,以便在activity 已暂停。否则,让您的 AsyncTask
一劳永逸可能没问题。 (创建它,执行它,让它超出范围。)
我不确定我正在尝试做的事情是否有意义,但我会试一试: 我的 phone 用作客户端,我需要将有关运动事件的数据发送到服务器。 我正在处理与 AsyncTask 的通信,所以我想在我的 AsyncTask class 中实现 onTouch 方法。 我让我的 AsyncTask 实现了 View.OnTouchListener 但事件并没有真正到达我的 AsyncTask 中的 onTouch 方法。 我猜我遗漏了一些非常基本的东西..
这是 AsyncTask 代码:
public class tpAsyncTask extends AsyncTask<String,String,String> implements View.OnTouchListener {
Context context;
boolean isCancelled = false;
float prevX;
float prevY;
Socket socket;
ObjectOutputStream oos;
private final static String TAG = "ME ASYNCTASK LOGGER: ";
public tpAsyncTask(Context context){
this.context = context;
}
@Override
protected String doInBackground(String... strings) {
String IP = strings[0];
String port = strings[1];
try {
InetAddress inetAddress = InetAddress.getByName(IP);
socket = new Socket(inetAddress,Integer.parseInt(port));
OutputStream os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
while(!isCancelled()) {
Thread.sleep(1000);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
try {
oos.flush();
oos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// PROBLEM IS THAT THE APP NEVER REACH HERE
if(!isCancelled()) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_MOVE:
{
Log.d(TAG, "ACTION MOVE IS PREFORMED");
}
case MotionEvent.ACTION_DOWN:
{
Log.d(TAG, "ACTION DOWN IS PREFORMED");
}
}
}
return false;
}}
谢谢
编辑,解决:
正如此处评论的许多人所说,我必须将我的 onTouch 实现附加到特定视图。
因此,由于我需要我的 onTouch 事件来包含所有屏幕尺寸,我只是创建了一个我的相对布局的对象并将其传递给我的 asyncTask(实现 OnTouchListener)的构造函数,并在我设置的构造函数上 myRelativeLayout.setOnTouchListerner(this)
.
成功了——asyncTask 中的 onTouch 方法现在在我触摸屏幕时被调用。
非常感谢大家。
有点缺乏信息。您是否使用
将 asyncTask 正确地放置在 onTouchListener 视图中view.setOnTouchListener(yourAsyncTask);
请注意,您的 AsyncTask 对象必须是 运行 对象(而不是新实例或匿名实例)。因此,我建议您在启动 运行 您的 asyncTask 时添加侦听器。
如果您已经这样做了,我建议您 post 更多信息(您的 activity 代码、asyncTask 启动和 setOnTouchListener 部分)。
编辑: 代码示例:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View viewToTouchWithReact=findViewById(R.id.yourViewId);
AsyncTask task=/**.AsynTask creation and launch.**/
viewToTouchWithReact.setOnTouchListener(task);
}
做那样的事情。如果没有启动 asyncTask 的代码和 activity 代码,我不能更精确。抱歉
无法访问代码,因为 AsyncTask 不是用户可以 'touched' 的 UI 元素。您应该将侦听器添加到视图,然后启动异步任务:
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
switch(motionEvent.getAction()) {
case MotionEvent.ACTION_MOVE:
{
tpAsyncTask<String,String,String> task = new tpAsyncTask<>();
task.execute(motionEvent);
Log.d(TAG, "ACTION MOVE IS PREFORMED");
}
case MotionEvent.ACTION_DOWN:
{
Log.d(TAG, "ACTION DOWN IS PREFORMED");
}
}
return false;
}
});
我认为你的客体关系有点由内而外。与其让你的 AsyncTask
拥有或成为 OnTouchListener
,不如让你的 OnTouchListener
(它总是在 UI 线程中调用)触发 AsyncTask
。
如果您的 AsyncTask
在完成后更新了 UI,那么您将需要跟踪 运行 AsyncTask
,以便在activity 已暂停。否则,让您的 AsyncTask
一劳永逸可能没问题。 (创建它,执行它,让它超出范围。)