我想从我的Android应用程序向mysql服务器发送数据。我有两张桌子。我使用Json格式使用PHP脚本发送数据。数据正在发送,但在发送数据并使应用程序崩溃后发生NullPointerException。有时数据发送两次,意味着数据重复发生。但是当我使用XAMPP在localhost中测试时,一切都很好。当尝试使用互联网向远程服务器发送数据时会发生这种情况。
这是我的java代码
public class SelectItem extends AppCompatActivity implements SelectItemAdapter.OnItemClickListener {
private Toolbar toolbar;
private String dealerName, dealerID, repID, orderId, newOrderId, orderIdForItemTable, json_string, numberPickerNumber;
private static final int TIME_DELAY = 2000;
private static long back_pressed;
private RecyclerView myRecyclerView;
private SelectItemAdapter myRecyclerViewAdapter;
private CartItemAdapter myCartItemAdapter;
private SQLiteHandler db;
private SessionManager session;
private LinearLayoutManager linearLayoutManager;
private SelectItemAdapter.ItemHolder selectItemAdapter;
private MaterialSuggestionAdapter adapter;
private JsonParseMaterial jpm;
private Button bAdd;
private ProgressDialog pDialog;
private RequestQueue requestQueue;
private VollySingleton vollySingleton;
private SQLiteHandler sqLiteHandler;
private static final String TAG = SQLiteHandler.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_item);
vollySingleton = VollySingleton.getsInstance();
requestQueue = vollySingleton.getmRequestQueue();
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
myRecyclerView = (RecyclerView) findViewById(R.id.selectedItemRecyclerView);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
sqLiteHandler = new SQLiteHandler(getApplicationContext());
myRecyclerViewAdapter = new SelectItemAdapter(this);
myRecyclerViewAdapter.setOnItemClickListener(this);
myRecyclerView.setAdapter(myRecyclerViewAdapter);
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerViewAdapter.notifyDataSetChanged();
dealerName = DealerListAdapter.getDealerName();
dealerID = DealerListAdapter.getDealerID();
repID = DealerListAdapter.getRepID();
//order number
orderId = "70000001";
if (newOrderId == null) {
newOrderId = orderId;
}
bAdd = (Button) findViewById(R.id.bAdd);
bAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (myRecyclerViewAdapter.getItemCount() != 0) {
checkOrderNo();
} else {
Toast.makeText(getApplicationContext(), "Empty List", Toast.LENGTH_SHORT).show();
}
}
});
//textView.setText(dealerName);
getSupportActionBar().setTitle(dealerName);
final AutoCompleteTextView acTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
adapter = new MaterialSuggestionAdapter(getApplicationContext());
acTextView.setAdapter(adapter);
acTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Product result = adapter.getItem(position);
String newName = result.getMatName().toString();
String newQty = String.valueOf(result.getMatQuantity());
String newPCode = result.getMatNo().toString();
String newPlant = result.getMatPlant().toString();
if (!newName.equals("")) {
if (myRecyclerViewAdapter.getItemCount() > 1) {
myRecyclerViewAdapter.add(1, newName, newQty, newPCode, newPlant);
} else {
myRecyclerViewAdapter.add(0, newName, newQty, newPCode, newPlant);
}
} else {
Toast.makeText(getApplicationContext(), "Product Already in the List", Toast.LENGTH_SHORT).show();
}
acTextView.setText("");
}
});
}
//send items for one order
private class SendItemAsync extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
}
@Override
protected Void doInBackground(Void... arg0) {
//Create JSON string start
json_string = "{\"sending_items\":[";
for (int i = 0; i < myRecyclerViewAdapter.getItemCount(); i++) {
if (myRecyclerView.findViewHolderForLayoutPosition(i) instanceof SelectItemAdapter.ItemHolder) {
SelectItemAdapter.ItemHolder childHolder = (SelectItemAdapter.ItemHolder) myRecyclerView.findViewHolderForLayoutPosition(i);
numberPickerNumber = childHolder.getQtyNumber();
}
//Repeat and loop this until all objects are added (and add try+catch)
try {
JSONObject obj_new = new JSONObject();
obj_new.put("order_no", orderIdForItemTable);
obj_new.put("items", myRecyclerViewAdapter.getItemName(i).toString());
obj_new.put("items_no", myRecyclerViewAdapter.getItemPCode(i).toString());
obj_new.put("plant", myRecyclerViewAdapter.getItemPlant(i).toString());
obj_new.put("quantity", numberPickerNumber);
json_string = json_string + obj_new.toString() + ",";
} catch (JSONException e) {
e.printStackTrace();
}
}
//Close JSON string
json_string = json_string.substring(0, json_string.length() - 1);
json_string += "]}";
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 3500);
HttpConnectionParams.setSoTimeout(httpParams, 1000);
HttpClient client = new DefaultHttpClient(httpParams);
String url = AppConfig.URL_ITEMS_SEND;
HttpPost request = new HttpPost(url);
try {
request.setEntity(new ByteArrayEntity(json_string.getBytes("UTF8")));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
request.setHeader("json", json_string);
request.setHeader("Accept", "application/json");
request.setHeader("Content-Type", "application/json");
Log.i("", "excuting request");
HttpResponse response = null;
try {
response = client.execute(request);
} catch (IOException e) {
e.printStackTrace();
}
Log.d("HTTP Response", response.getStatusLine().toString());
try {
String responseBody = EntityUtils.toString(response.getEntity());
Log.d("Server Response", responseBody);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
finish();
Bundle basket = new Bundle();
basket.putString("dealerName", dealerName);
basket.putString("orderNo", newOrderId);
basket.putString("jsonString", json_string);
Intent intent = new Intent(SelectItem.this, ItemCart.class);
intent.putExtras(basket);
startActivity(intent);
finish();
//Toast.makeText(getApplicationContext(), json_string, Toast.LENGTH_LONG).show();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.sub_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.toolbar_logo) {
Toast.makeText(getApplicationContext(), "cart", Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onItemClick(SelectItemAdapter.ItemHolder item, int position) {
Toast.makeText(this,
"Remove " + position + " : " + item.getItemName(),
Toast.LENGTH_SHORT).show();
myRecyclerViewAdapter.remove(position);
}
private void checkOrderNo() {
showDialog();
DateFormat df = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
final String nowDate = df.format(new Date());
//final day of the month
Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.DATE, -1);
Date lastDayOfMonth = calendar.getTime();
DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
final String lastDate = sdf.format(lastDayOfMonth);
Log.d("Last day ", sdf.format(lastDayOfMonth) + " // Today" + nowDate);
// Tag used to cancel the insert
String tag_string_req = "req_insert";
final StringRequest strReq = new StringRequest(Request.Method.POST,
AppConfig.URL_ITEM_DETAILS_SEND, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
if (jObj.names().get(0).equals("found")) {
newOrderId = jObj.getString("found").toString();
orderIdForItemTable = newOrderId;
new SendItemAsync().execute();
Log.d(TAG, "newOrderId: " + newOrderId);
Log.d(TAG, "New repID 2 inserted into sqlite: " + newOrderId + " " + nowDate);
sqLiteHandler.addItemDetails(newOrderId, repID, dealerID, nowDate, lastDate);
} else {
Toast.makeText(getApplicationContext(), "Invalied Request", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Inserting Error: " + error.getMessage());
Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("order_no", orderId);
params.put("repID", repID);
params.put("dealerID", dealerID);
params.put("nowDate", nowDate);
params.put("lastDate", lastDate);
return params;
}
};
strReq.setRetryPolicy(new DefaultRetryPolicy(3500, 0,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
我的logCat
04-05 13:08:08.144 11370-11370/com.ceatkelanisrilanka.dushanmadushanka.ceat D/SQLiteHandler: newOrderId: 70000006
04-05 13:08:08.144 11370-11370/com.ceatkelanisrilanka.dushanmadushanka.ceat D/SQLiteHandler: New repID 2 inserted into sqlite: 70000006 2016/04/05 01:08:05
[ 04-05 13:08:08.150 11370:11544 I/ ]
excuting request
04-05 13:08:08.166 11370-11370/com.ceatkelanisrilanka.dushanmadushanka.ceat D/SQLiteHandler: New details inserted into sqlite: 5
04-05 13:08:09.196 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: java.net.SocketTimeoutException
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:37)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:160)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:84)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:273)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:260)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:283)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:251)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:197)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:271)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:685)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:487)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:860)
04-05 13:08:09.197 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at cz.msebera.android.httpclient.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at com.ceatkelanisrilanka.dushanmadushanka.ceat.SelectItem$SendItemAsync.doInBackground(SelectItem.java:233)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at com.ceatkelanisrilanka.dushanmadushanka.ceat.SelectItem$SendItemAsync.doInBackground(SelectItem.java:177)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:292)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
04-05 13:08:09.198 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat W/System.err: at java.lang.Thread.run(Thread.java:818)
04-05 13:08:09.207 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.ceatkelanisrilanka.dushanmadushanka.ceat, PID: 11370
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'cz.msebera.android.httpclient.StatusLine cz.msebera.android.httpclient.HttpResponse.getStatusLine()' on a null object reference
at com.ceatkelanisrilanka.dushanmadushanka.ceat.SelectItem$SendItemAsync.doInBackground(SelectItem.java:237)
at com.ceatkelanisrilanka.dushanmadushanka.ceat.SelectItem$SendItemAsync.doInBackground(SelectItem.java:177)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
04-05 13:08:09.250 11370-11402/com.ceatkelanisrilanka.dushanmadushanka.ceat W/EGL_emulation: eglSurfaceAttrib not implemented
04-05 13:08:09.251 11370-11402/com.ceatkelanisrilanka.dushanmadushanka.ceat W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xe233fe60, error=EGL_SUCCESS
04-05 13:13:09.223 11370-11544/com.ceatkelanisrilanka.dushanmadushanka.ceat I/Process: Sending signal. PID: 11370 SIG: 9
我的PHP脚本
<?php
require_once 'include/Configg.php';
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die("connection failed");
mysql_select_db(DB_DATABASE,$con) or die("db selection failed");
$order_no = $repID = $dealerID = $nowDate = $lastDate = "";
if(isset($_POST['order_no'])){
$order_no = $_POST['order_no'];
$repID = $_POST['repID'];
$dealerID = $_POST['dealerID'];
$nowDate = $_POST['nowDate'];
$lastDate = $_POST['lastDate'];
}
$result = mysql_query("SELECT MAX(order_no) FROM items_details");
$row = mysql_fetch_row($result);
if($row[0] < 70000000){
$highest_id = 70000000;
} else{
$highest_id = $row[0] + '1';
}
//$highest_id = $row[0] + '1';
$query = mysql_query("INSERT INTO items_details(order_no,rep_no,dealer_no,order_date,last_date) VALUES('$highest_id','$repID','$dealerID','$nowDate','$lastDate')");
$json['found']= $highest_id;
echo json_encode($json);
?>
其他表的第二个脚本
<?php
require_once 'include/Configg.php';
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die("connection failed");
mysql_select_db(DB_DATABASE,$con) or die("db selection failed");
$postdata = file_get_contents('php://input');
$data = json_decode($postdata, true);
if (is_array($data['sending_items'])) {
foreach ($data['sending_items'] as $record) {
$order_no = $record['order_no'];
$items = $record['items'];
$items_no = $record['items_no'];
$plant = $record['plant'];
$quantity = $record['quantity'];
mysql_query("INSERT INTO item_list(order_no, items, items_no, plant, quantity) VALUES('$order_no', '$items', '$items_no', '$plant', '$quantity')");
}
}
echo json_encode($data);
mysql_close($con);
?>
答案 0 :(得分:0)
您在这里设置Response
到null
。
HttpResponse response = null;
try {
response = client.execute(request); // trying to execute to get reponse
} catch (IOException e) {
e.printStackTrace(); // if fails, response remains null.
}
// if successful no problem, if failed you are getting null pointer exception as response is null.
Log.d("HTTP Response", response.getStatusLine().toString());
失败原因是SocketTimeoutException
,这意味着您的远程服务器无法访问。所以你应该处理这种情况并格式化如下代码:
HttpResponse response = null;
try {
response = client.execute(request);
Log.d("HTTP Response", response.getStatusLine().toString());
try {
String responseBody = EntityUtils.toString(response.getEntity());
Log.d("Server Response", responseBody);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
另请注意:我注意到您已在代码中加入volley
。
答案 1 :(得分:0)
try
中有几个catch
和doInBackground
语句导致程序中出现此类错误。当出现问题并且抛出Exception
时,您应该立即从您的函数返回。
以下是有关您的代码的一些建议:
将AsyncTask
签名更改为以下内容:
private class SendItemAsync extends AsyncTask<Void, Void, Boolean> {
在您的doInBackground
函数中,更改您尝试的行为并抓住:
try {
JSONObject obj_new = new JSONObject();
obj_new.put("order_no", orderIdForItemTable);
obj_new.put("items", myRecyclerViewAdapter.getItemName(i).toString());
obj_new.put("items_no", myRecyclerViewAdapter.getItemPCode(i).toString());
obj_new.put("plant", myRecyclerViewAdapter.getItemPlant(i).toString());
obj_new.put("quantity", numberPickerNumber);
json_string = json_string + obj_new.toString() + ",";
}
catch (JSONException e) {
e.printStackTrace();
return new Boolean(false);
}
...
try {
request.setEntity(new ByteArrayEntity(json_string.getBytes("UTF8")));
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
return new Boolean(false);
}
try {
response = client.execute(request);
}
catch (IOException e) {
e.printStackTrace();
return new Boolean(false);
}
...
try {
String responseBody = EntityUtils.toString(response.getEntity());
Log.d("Server Response", responseBody);
}
catch (IOException e) {
e.printStackTrace();
return new Boolean(false);
}
return true;
最后更改您的onPostExecute
以处理错误情况:
protected void onPostExecute(Boolean noError) {
if(!noError)
return;
finish();
Bundle basket = new Bundle();
basket.putString("dealerName", dealerNam
...